{
  "version": 3,
  "sources": ["../../../../crdtree2/src/table/branchId.ts", "../../../../crdtree2/src/utils.ts", "../../../../crdtree2/src/timestamp.ts"],
  "sourcesContent": ["/**\n * Identifier of the implicit \"main\" branch. Every {@link Table} starts with a\n * single {@link TableBranchData} keyed by this id; non-main branches use the\n * NodeID of their corresponding `BranchNode` as their identifier.\n */\nexport const MAIN_BRANCH_ID = \"main\"\n\n/**\n * Key on a branch's config row that names the parent branch this branch was\n * forked from. The value is either {@link MAIN_BRANCH_ID} or the NodeID of\n * another `BranchNode`.\n */\nexport const BRANCH_BASE_ID_KEY = \"baseId\"\n", "import type { ColumnData } from \"./table/TableBranchData.ts\"\n\n/**\n * FNV-1a 32-bit string hash. Returns an unsigned 32-bit integer.\n *\n * Constraints:\n * - Iterates UTF-16 code units (`charCodeAt`), so the same string in two\n *   different unicode normalisations will hash differently. Safe for ASCII;\n *   for arbitrary unicode encode to UTF-8 bytes first.\n * - Not cryptographic \u2014 collision-resistant only in the statistical sense.\n * - Distribution is good enough for short structured inputs that the\n *   collision rate approximates uniform over the 2^32 output space.\n */\nexport function fnv1a32(str: string): number {\n\tlet hash = 0x811c9dc5\n\tfor (let i = 0; i < str.length; i++) {\n\t\thash ^= str.charCodeAt(i)\n\t\thash = Math.imul(hash, 0x01000193)\n\t}\n\treturn hash >>> 0\n}\n\nexport const getUInt16Hash = (str: string): number => {\n\tlet hash = 5381\n\tfor (let i = 0; i < str.length; i++) {\n\t\thash = (hash << 5) + hash + str.charCodeAt(i)\n\t}\n\treturn hash & 0xffff\n}\n\nexport function isObject(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value)\n}\n\n/** Returns true if seqA is newer than seqB. */\nexport function isNewer(seqA: number, clientA: number, seqB: number, clientB: number): boolean {\n\treturn seqA === seqB ? clientA > clientB : seqA > seqB\n}\n\nexport function isNewerFast(cols: ColumnData, idxA: number, idxB: number) {\n\tconst seqA = cols.seq.get(idxA)\n\tconst seqB = cols.seq.get(idxB)\n\tif (seqA === seqB) {\n\t\tconst clientA = cols.client.get(idxA)\n\t\tconst clientB = cols.client.get(idxB)\n\t\treturn clientA > clientB\n\t}\n\n\treturn seqA > seqB\n}\n\nexport function isEqualAtomicArray(a: unknown[], b: unknown[]): boolean {\n\tif (a.length !== b.length) return false\n\n\tfor (let i = 0; i < a.length; i++) {\n\t\tconst aItem = a[i]\n\t\tconst bItem = b[i]\n\n\t\tif (Array.isArray(aItem) && Array.isArray(bItem)) {\n\t\t\tif (!isEqualAtomicArray(aItem, bItem)) return false\n\t\t} else if (!Object.is(aItem, bItem)) {\n\t\t\treturn false\n\t\t}\n\t}\n\n\treturn true\n}\n", "import { assert } from \"@framerjs/shared\"\nimport { MAIN_BRANCH_ID } from \"./table/branchId.ts\"\nimport { fnv1a32 } from \"./utils.ts\"\n\nconst MAX_INTEGER_U32 = 2 ** 32 - 1\nconst RESERVED_CLIENTS = 10\n\nconst CLIENT_ID_RANGE = MAX_INTEGER_U32 - RESERVED_CLIENTS\n\n/** The reserved client ids, highest first (MAX_INTEGER_U32 down through the reserved range). */\nexport const RESERVED_CLIENT_IDS: readonly number[] = Array.from(\n\t{ length: RESERVED_CLIENTS },\n\t(_, i) => MAX_INTEGER_U32 - i,\n)\n\nexport function generateRandomClientId(): number {\n\t// The last 10 numbers of the u32 range are reserved client IDs\n\treturn Math.floor(Math.random() * CLIENT_ID_RANGE)\n}\n\nexport function isValidClientId(clientId: number): boolean {\n\treturn Number.isSafeInteger(clientId) && clientId >= 0 && clientId <= CLIENT_ID_RANGE\n}\n\nexport function isValidSeq(seq: number): boolean {\n\treturn Number.isSafeInteger(seq) && seq >= 0\n}\n\n/**\n * Derives the clientId used for position ID ordering on a given branch.\n * Main branch uses the raw clientId so ordering is stable with pre-branch\n * history; non-main branches hash `(branchId, clientId)` into the valid clientId\n * range so edits on branches without visibility of each other don't share keys.\n */\nexport function derivePositionClientId(branchId: string, clientId: number): number {\n\tconst derived = branchId === MAIN_BRANCH_ID ? clientId : fnv1a32(`${branchId}:${clientId}`) % CLIENT_ID_RANGE\n\tassert(isValidClientId(derived), \"invalid clientId derived for\", `${branchId}:${clientId}`, derived)\n\treturn derived\n}\n"],
  "mappings": ";;;;;AAKO,IAAM,iBAAiB;AAOvB,IAAM,qBAAqB;;;ACC3B,SAAS,QAAQ,KAAqB;AAC5C,MAAI,OAAO;AACX,WAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK;AACpC,YAAQ,IAAI,WAAW,CAAC;AACxB,WAAO,KAAK,KAAK,MAAM,QAAU;AAAA,EAClC;AACA,SAAO,SAAS;AACjB;AAUO,SAAS,SAAS,OAAkD;AAC1E,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC3E;AAGO,SAAS,QAAQ,MAAc,SAAiB,MAAc,SAA0B;AAC9F,SAAO,SAAS,OAAO,UAAU,UAAU,OAAO;AACnD;AAEO,SAAS,YAAY,MAAkB,MAAc,MAAc;AACzE,QAAM,OAAO,KAAK,IAAI,IAAI,IAAI;AAC9B,QAAM,OAAO,KAAK,IAAI,IAAI,IAAI;AAC9B,MAAI,SAAS,MAAM;AAClB,UAAM,UAAU,KAAK,OAAO,IAAI,IAAI;AACpC,UAAM,UAAU,KAAK,OAAO,IAAI,IAAI;AACpC,WAAO,UAAU;AAAA,EAClB;AAEA,SAAO,OAAO;AACf;AAEO,SAAS,mBAAmB,GAAc,GAAuB;AACvE,MAAI,EAAE,WAAW,EAAE,OAAQ,QAAO;AAElC,WAAS,IAAI,GAAG,IAAI,EAAE,QAAQ,KAAK;AAClC,UAAM,QAAQ,EAAE,CAAC;AACjB,UAAM,QAAQ,EAAE,CAAC;AAEjB,QAAI,MAAM,QAAQ,KAAK,KAAK,MAAM,QAAQ,KAAK,GAAG;AACjD,UAAI,CAAC,mBAAmB,OAAO,KAAK,EAAG,QAAO;AAAA,IAC/C,WAAW,CAAC,OAAO,GAAG,OAAO,KAAK,GAAG;AACpC,aAAO;AAAA,IACR;AAAA,EACD;AAEA,SAAO;AACR;;;AC9DA,IAAM,kBAAkB,KAAK,KAAK;AAClC,IAAM,mBAAmB;AAEzB,IAAM,kBAAkB,kBAAkB;AAGnC,IAAM,sBAAyC,MAAM;AAAA,EAC3D,EAAE,QAAQ,iBAAiB;AAAA,EAC3B,CAAC,GAAG,MAAM,kBAAkB;AAC7B;AAEO,SAAS,yBAAiC;AAEhD,SAAO,KAAK,MAAM,KAAK,OAAO,IAAI,eAAe;AAClD;AAEO,SAAS,gBAAgB,UAA2B;AAC1D,SAAO,OAAO,cAAc,QAAQ,KAAK,YAAY,KAAK,YAAY;AACvE;AAEO,SAAS,WAAW,KAAsB;AAChD,SAAO,OAAO,cAAc,GAAG,KAAK,OAAO;AAC5C;AAQO,SAAS,uBAAuB,UAAkB,UAA0B;AAClF,QAAM,UAAU,aAAa,iBAAiB,WAAW,QAAQ,GAAG,QAAQ,IAAI,QAAQ,EAAE,IAAI;AAC9F,SAAO,gBAAgB,OAAO,GAAG,gCAAgC,GAAG,QAAQ,IAAI,QAAQ,IAAI,OAAO;AACnG,SAAO;AACR;",
  "names": []
}
