@moyodb/sdk 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,12 +6,16 @@ const CONTROL_VERSION = 1;
6
6
  const CONTROL_CHECKSUM_OFFSET = 24;
7
7
  const CONTROL_NAME_OFFSET = 32;
8
8
  const CONTROL_MAGIC = new Uint8Array([66, 68, 66, 82, 79, 79, 84, 49]);
9
- const OPFS_WRITE_CHUNK_SIZE = 256 * 1024;
9
+ // Chromium rejects a SyncAccessHandle.write larger than a signed 32-bit count.
10
+ const OPFS_MAX_WRITE_SIZE = 0x7fffffff;
10
11
  const TEXT_ENCODER = new TextEncoder();
11
12
  const TEXT_DECODER = new TextDecoder();
12
13
  let rootDir = null;
13
14
  let nextSessionId = 1;
14
15
  const sessions = new Map();
16
+ // Exclusive session handles keep cached sizes valid across Rust backend clones.
17
+ // Length checks for validation and statistics still query OPFS.
18
+ const appendOffsets = new WeakMap();
15
19
  function namedError(name, message) {
16
20
  const error = new Error(message);
17
21
  error.name = name;
@@ -67,7 +71,7 @@ function writeU64(view, offset, value) {
67
71
  view.setBigUint64(offset, BigInt(value), true);
68
72
  }
69
73
  function readU64(view, offset) {
70
- return Number(view.getBigUint64(offset, true));
74
+ return view.getBigUint64(offset, true);
71
75
  }
72
76
  function fnv1a32(bytes, zeroOffset = -1, zeroLength = 0) {
73
77
  let hash = 0x811c9dc5;
@@ -82,12 +86,14 @@ function fnv1a32(bytes, zeroOffset = -1, zeroLength = 0) {
82
86
  function isGenerationNameValid(name) {
83
87
  return typeof name === 'string' && /^gen-[a-z0-9]+-[a-z0-9]+$/i.test(name);
84
88
  }
85
- // Every byte must reach the file or the call fails: a short write that returns
86
- // normally would let callers publish state that is not on disk.
89
+ // Returns only after all bytes are written. The caller must flush for durability.
87
90
  export function writeAll(handle, bytes, at) {
88
91
  let writtenTotal = 0;
89
92
  while (writtenTotal < bytes.length) {
90
- const chunk = bytes.subarray(writtenTotal, writtenTotal + OPFS_WRITE_CHUNK_SIZE);
93
+ // Preserve the engine's batch; split only at the browser size limit or
94
+ // after a short write. Suffix views borrow the original buffer.
95
+ const end = Math.min(bytes.length, writtenTotal + OPFS_MAX_WRITE_SIZE);
96
+ const chunk = writtenTotal === 0 && end === bytes.length ? bytes : bytes.subarray(writtenTotal, end);
91
97
  const rawWritten = handle.write(chunk, { at: at + writtenTotal });
92
98
  const written = Number(rawWritten);
93
99
  if (!Number.isSafeInteger(written) || written < 0 || written > chunk.length) {
@@ -100,7 +106,7 @@ export function writeAll(handle, bytes, at) {
100
106
  }
101
107
  return writtenTotal;
102
108
  }
103
- // Fills `buffer` from `at`, stopping only at end of file. Bytes past EOF stay zero.
109
+ // Reads until the buffer is full or a read returns zero. The unread suffix is unchanged.
104
110
  export function readAll(handle, buffer, at) {
105
111
  let readTotal = 0;
106
112
  while (readTotal < buffer.length) {
@@ -138,8 +144,8 @@ export function encodeControlSlot(generationCounter, activeGeneration) {
138
144
  view.setUint32(CONTROL_CHECKSUM_OFFSET, checksum, true);
139
145
  return slot;
140
146
  }
141
- // Returns null for any slot whose bytes do not checksum. Fields are interpreted
142
- // only after the checksum passes, so a torn slot never masks its valid sibling.
147
+ // Reject incomplete slots and bad magic or checksums. Validate the remaining
148
+ // fields after the checksum passes, so torn fields cannot mask a valid slot.
143
149
  export function decodeControlSlot(slotIndex, bytes) {
144
150
  if (bytes.length < CONTROL_SLOT_SIZE) {
145
151
  return null;
@@ -174,9 +180,9 @@ export function decodeControlSlot(slotIndex, bytes) {
174
180
  activeGeneration
175
181
  };
176
182
  }
177
- // `absent` — the file is empty: no generation has ever been published.
178
- // `invalid` — the file has bytes but no slot checksums.
179
- // `valid` — `control` is the newest checksummed slot.
183
+ // `absent`: empty file.
184
+ // `invalid`: nonempty file with no valid slot.
185
+ // `valid`: `control` is the valid slot with the highest generation counter.
180
186
  export function readControlStateFromAccessHandle(accessHandle) {
181
187
  const size = Number(accessHandle.getSize());
182
188
  if (!Number.isSafeInteger(size) || size < 0) {
@@ -207,21 +213,18 @@ async function readControlFile(dbRoot) {
207
213
  accessHandle.close();
208
214
  }
209
215
  }
210
- async function hasLegacyDataFiles(dbRoot) {
211
- for (const fileName of FILE_NAMES) {
212
- if (await lookupFileHandle(dbRoot, fileName)) {
213
- return true;
214
- }
216
+ async function hasLegacyDataFiles(dbRoot, fileKind = 0) {
217
+ if (fileKind === FILE_NAMES.length) {
218
+ return false;
219
+ }
220
+ if (await lookupFileHandle(dbRoot, FILE_NAMES[fileKind])) {
221
+ return true;
215
222
  }
216
- return false;
223
+ return await hasLegacyDataFiles(dbRoot, fileKind + 1);
217
224
  }
218
- // Resolves which directory holds the live database, failing closed on damage.
219
- //
220
- // Legacy root files are removed before the first write into a published
221
- // generation (see opfsCleanupInactiveEntries and opfsOpenActiveDb). So an
222
- // unreadable control file next to legacy files can only be a torn first
223
- // publication, and legacy is still authoritative. Without legacy files it is
224
- // real corruption of the pointer to live data.
225
+ // Legacy files remain authoritative after a torn first publication. They must
226
+ // be removed before a published generation accepts writes, so later control
227
+ // damage cannot make stale legacy files appear current.
225
228
  async function resolveActiveGeneration(dbRoot) {
226
229
  const state = await readControlFile(dbRoot);
227
230
  if (state.status === 'valid') {
@@ -251,7 +254,11 @@ async function writeControlState(dbRoot, activeGeneration, expectedCurrentGenera
251
254
  );
252
255
  }
253
256
  const nextSlot = current.control ? (current.control.slotIndex === 0 ? 1 : 0) : 0;
254
- const nextGenerationCounter = (current.control?.generationCounter ?? 0) + 1;
257
+ const generationCounter = current.control?.generationCounter ?? 0n;
258
+ if (generationCounter === 0xffffffffffffffffn) {
259
+ throw namedError('StorageError', 'control generation counter exhausted');
260
+ }
261
+ const nextGenerationCounter = generationCounter + 1n;
255
262
  const encoded = encodeControlSlot(nextGenerationCounter, activeGeneration);
256
263
  writeAll(accessHandle, encoded, nextSlot * CONTROL_SLOT_SIZE);
257
264
  accessHandle.flush();
@@ -274,19 +281,29 @@ function createGenerationName() {
274
281
  const randomPart = Array.from(randomBytes, (byte) => byte.toString(16).padStart(2, '0')).join('');
275
282
  return `gen-${timePart}-${randomPart}`;
276
283
  }
284
+ async function createGenerationDirectory(dbRoot) {
285
+ const generationName = createGenerationName();
286
+ if (await lookupDirectoryHandle(dbRoot, generationName)) {
287
+ return await createGenerationDirectory(dbRoot);
288
+ }
289
+ await dbRoot.getDirectoryHandle(generationName, { create: true });
290
+ return generationName;
291
+ }
277
292
  async function getDbRoot(encodedDbName, createIfMissing) {
278
293
  const stackdb = await getOrCreateStackdbRoot();
279
- let dbRoot = await lookupDirectoryHandle(stackdb, encodedDbName);
294
+ if (createIfMissing) {
295
+ // Creation also opens existing directories, avoiding a separate lookup.
296
+ return await stackdb.getDirectoryHandle(encodedDbName, { create: true });
297
+ }
298
+ const dbRoot = await lookupDirectoryHandle(stackdb, encodedDbName);
280
299
  if (!dbRoot) {
281
- if (!createIfMissing) {
282
- throw new Error(`database ${encodedDbName} does not exist`);
283
- }
284
- dbRoot = await stackdb.getDirectoryHandle(encodedDbName, { create: true });
300
+ throw new Error(`database ${encodedDbName} does not exist`);
285
301
  }
286
302
  return dbRoot;
287
303
  }
288
304
  async function removeLegacyDataFiles(dbRoot) {
289
- for (const fileName of FILE_NAMES) {
305
+ await FILE_NAMES.reduce(async (previous, fileName) => {
306
+ await previous;
290
307
  try {
291
308
  await dbRoot.removeEntry(fileName);
292
309
  } catch (err) {
@@ -294,7 +311,7 @@ async function removeLegacyDataFiles(dbRoot) {
294
311
  throw err;
295
312
  }
296
313
  }
297
- }
314
+ }, Promise.resolve());
298
315
  }
299
316
  async function resolveActiveDataDir(dbRoot) {
300
317
  const activeGeneration = await resolveActiveGeneration(dbRoot);
@@ -309,8 +326,7 @@ async function resolveActiveDataDir(dbRoot) {
309
326
  if (!activeDir) {
310
327
  throw corruptionError(`active generation ${activeGeneration} is missing`);
311
328
  }
312
- // A crash after publication but before legacy cleanup leaves stale root
313
- // files. They must be gone before this generation accepts writes.
329
+ // Remove stale legacy files before writes can make this generation newer.
314
330
  await removeLegacyDataFiles(dbRoot);
315
331
  return {
316
332
  dirHandle: activeDir,
@@ -324,9 +340,10 @@ function closeSession(sessionId) {
324
340
  return;
325
341
  }
326
342
  for (const handle of session.handles.values()) {
343
+ appendOffsets.delete(handle);
327
344
  try {
328
345
  handle.close();
329
- } catch (_err) {}
346
+ } catch {}
330
347
  }
331
348
  sessions.delete(sessionId);
332
349
  }
@@ -339,24 +356,34 @@ function closeSessionsForDb(encodedDbName) {
339
356
  }
340
357
  }
341
358
  async function openSessionForDir(dbPath, dirHandle, generationName) {
342
- const handles = new Map();
343
- try {
344
- for (let fileKind = 0; fileKind < FILE_NAMES.length; fileKind += 1) {
345
- const fileName = FILE_NAMES[fileKind];
359
+ // Acquire independent files concurrently. Publish the session only after
360
+ // all handles are acquired; failures must release every acquired handle.
361
+ const opened = await Promise.allSettled(
362
+ FILE_NAMES.map(async (fileName) => {
346
363
  const fileHandle = await dirHandle.getFileHandle(fileName, { create: true });
347
364
  if (typeof fileHandle.createSyncAccessHandle !== 'function') {
348
365
  throw new Error('createSyncAccessHandle is unavailable');
349
366
  }
350
- const accessHandle = await fileHandle.createSyncAccessHandle();
351
- handles.set(fileKind, accessHandle);
367
+ return await fileHandle.createSyncAccessHandle();
368
+ })
369
+ );
370
+ const handles = new Map();
371
+ for (let fileKind = 0; fileKind < opened.length; fileKind += 1) {
372
+ const result = opened[fileKind];
373
+ if (result.status === 'fulfilled') {
374
+ handles.set(fileKind, result.value);
352
375
  }
353
- } catch (error) {
376
+ }
377
+ const failed = opened.find((result) => result.status === 'rejected');
378
+ if (failed) {
379
+ // Waiting for all results also captures late successes for cleanup.
354
380
  for (const handle of handles.values()) {
355
381
  try {
356
382
  handle.close();
357
- } catch (_err) {}
383
+ } catch {}
358
384
  }
359
- throw error;
385
+ // Error precedence follows FILE_NAMES order, regardless of completion order.
386
+ throw failed.reason;
360
387
  }
361
388
  const sessionId = nextSessionId;
362
389
  nextSessionId += 1;
@@ -381,11 +408,29 @@ function getAccessHandle(sessionId, fileKind) {
381
408
  }
382
409
  return handle;
383
410
  }
411
+ function rememberFileSize(handle, size) {
412
+ if (typeof size === 'number' && Number.isSafeInteger(size) && size >= 0) {
413
+ appendOffsets.set(handle, size);
414
+ } else {
415
+ appendOffsets.delete(handle);
416
+ }
417
+ }
418
+ function readFileSize(handle) {
419
+ try {
420
+ const size = handle.getSize();
421
+ rememberFileSize(handle, size);
422
+ return size;
423
+ } catch (error) {
424
+ appendOffsets.delete(handle);
425
+ throw error;
426
+ }
427
+ }
384
428
  function lookupOpenFileSize(path) {
385
429
  for (const session of sessions.values()) {
386
430
  for (let fileKind = 0; fileKind < FILE_NAMES.length; fileKind += 1) {
387
431
  if (`${session.path}/${FILE_NAMES[fileKind]}` === path) {
388
- return Number(session.handles.get(fileKind)?.getSize() ?? 0);
432
+ const handle = session.handles.get(fileKind);
433
+ return Number((handle ? readFileSize(handle) : 0) ?? 0);
389
434
  }
390
435
  }
391
436
  }
@@ -426,6 +471,14 @@ export async function opfsReadActiveGeneration(encodedDbName) {
426
471
  const dbRoot = await getDbRoot(encodedDbName, false);
427
472
  return await resolveActiveGeneration(dbRoot);
428
473
  }
474
+ // The WASM view is valid only during this synchronous call. Zero the unread
475
+ // suffix to preserve the backend read contract when the destination is reused.
476
+ export function opfsReadAtInto(sessionId, fileKind, offset, buffer) {
477
+ const handle = getAccessHandle(sessionId, fileKind);
478
+ const read = readAll(handle, buffer, Number(offset));
479
+ buffer.fill(0, read);
480
+ return read;
481
+ }
429
482
  export function opfsReadAt(sessionId, fileKind, offset, len) {
430
483
  const handle = getAccessHandle(sessionId, fileKind);
431
484
  const buffer = new Uint8Array(len);
@@ -433,32 +486,67 @@ export function opfsReadAt(sessionId, fileKind, offset, len) {
433
486
  return buffer;
434
487
  }
435
488
  export function opfsWriteAt(sessionId, fileKind, offset, bytes) {
436
- return writeAll(getAccessHandle(sessionId, fileKind), bytes, Number(offset));
489
+ const handle = getAccessHandle(sessionId, fileKind);
490
+ try {
491
+ const at = Number(offset);
492
+ const written = writeAll(handle, bytes, at);
493
+ // Empty writes cannot extend the file. A successful overwrite alone
494
+ // cannot establish the full file length.
495
+ if (written > 0) {
496
+ const previous = appendOffsets.get(handle);
497
+ const end = at + written;
498
+ if (previous !== undefined && Number.isSafeInteger(at) && at >= 0 && Number.isSafeInteger(end)) {
499
+ appendOffsets.set(handle, Math.max(previous, end));
500
+ } else {
501
+ appendOffsets.delete(handle);
502
+ }
503
+ }
504
+ return written;
505
+ } catch (error) {
506
+ // A failed write may leave a prefix. The next append must read the
507
+ // actual file length, even when the thrown value is not an Error.
508
+ appendOffsets.delete(handle);
509
+ throw error;
510
+ }
437
511
  }
438
512
  export function opfsFlush(sessionId, fileKind) {
439
- getAccessHandle(sessionId, fileKind).flush();
513
+ const handle = getAccessHandle(sessionId, fileKind);
514
+ try {
515
+ handle.flush();
516
+ } catch (error) {
517
+ appendOffsets.delete(handle);
518
+ throw error;
519
+ }
440
520
  }
441
521
  export function opfsLen(sessionId, fileKind) {
442
- return BigInt(getAccessHandle(sessionId, fileKind).getSize());
522
+ return BigInt(readFileSize(getAccessHandle(sessionId, fileKind)));
523
+ }
524
+ export function opfsAppendOffset(sessionId, fileKind) {
525
+ const handle = getAccessHandle(sessionId, fileKind);
526
+ const size = appendOffsets.get(handle);
527
+ return size === undefined ? opfsLen(sessionId, fileKind) : BigInt(size);
443
528
  }
444
529
  export function opfsTruncate(sessionId, fileKind, size) {
445
- getAccessHandle(sessionId, fileKind).truncate(Number(size));
530
+ const handle = getAccessHandle(sessionId, fileKind);
531
+ try {
532
+ const length = Number(size);
533
+ handle.truncate(length);
534
+ rememberFileSize(handle, length);
535
+ } catch (error) {
536
+ appendOffsets.delete(handle);
537
+ throw error;
538
+ }
446
539
  }
447
540
  export function opfsCloseSession(sessionId) {
448
541
  closeSession(sessionId);
449
542
  }
450
543
  export async function opfsPrepareRebuildTarget(encodedDbName) {
451
544
  const dbRoot = await getDbRoot(encodedDbName, true);
452
- let generationName = createGenerationName();
453
- while (await lookupDirectoryHandle(dbRoot, generationName)) {
454
- generationName = createGenerationName();
455
- }
456
- await dbRoot.getDirectoryHandle(generationName, { create: true });
545
+ const generationName = await createGenerationDirectory(dbRoot);
457
546
  return { generationName };
458
547
  }
459
- // Publishes `generationName` as the live database. Resolves only after the
460
- // control file has been flushed and read back selecting the new generation;
461
- // the caller may switch its live engine only after that.
548
+ // Resolves after the control file is flushed and verified to select the new
549
+ // generation. The caller may then switch its live engine.
462
550
  export async function opfsSwapActiveGeneration(encodedDbName, generationName, expectedCurrentGeneration) {
463
551
  if (!isGenerationNameValid(generationName)) {
464
552
  throw new Error(`invalid generation name ${generationName}`);
@@ -470,8 +558,8 @@ export async function opfsSwapActiveGeneration(encodedDbName, generationName, ex
470
558
  }
471
559
  await writeControlState(dbRoot, generationName, expectedCurrentGeneration ?? null);
472
560
  }
473
- // Legacy root files are removed strictly (see resolveActiveGeneration); stale
474
- // generation directories are best effort because nothing can select them.
561
+ // Legacy-file removal must succeed to prevent stale fallback after control
562
+ // damage. Inactive generation cleanup is best effort.
475
563
  export async function opfsCleanupInactiveEntries(encodedDbName) {
476
564
  const dbRoot = await lookupDirectoryHandle(await getOrCreateStackdbRoot(), encodedDbName);
477
565
  if (!dbRoot) {
@@ -487,11 +575,12 @@ export async function opfsCleanupInactiveEntries(encodedDbName) {
487
575
  staleDirectories.push(name);
488
576
  }
489
577
  }
490
- for (const name of staleDirectories) {
578
+ await staleDirectories.reduce(async (previous, name) => {
579
+ await previous;
491
580
  try {
492
581
  await dbRoot.removeEntry(name, { recursive: true });
493
- } catch (_err) {}
494
- }
582
+ } catch {}
583
+ }, Promise.resolve());
495
584
  }
496
585
  export async function opfsDbDirectorySize(encodedDbName) {
497
586
  const dbRoot = await lookupDirectoryHandle(await getOrCreateStackdbRoot(), encodedDbName);
package/dist/errors.d.ts CHANGED
@@ -65,9 +65,9 @@ export declare class ChangeFeedCompactedError extends MoyoDbError {
65
65
  constructor(message: string);
66
66
  }
67
67
  /**
68
- * The outcome of a commit could not be confirmed (storage failed at or after
69
- * the WAL append) or the engine hit an unrecoverable fault. The database
70
- * rejects further work until it is reopened, which replays durable state.
68
+ * The engine state could not be trusted, or automatic recovery failed.
69
+ * A failed commit may already be durable. The worker attempts recovery before
70
+ * a new transaction and after a failed commit. Recovery discards all open transactions.
71
71
  */
72
72
  export declare class RecoveryRequiredError extends MoyoDbError {
73
73
  constructor(message: string);
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAMR,EAAE,EAMF,WAAW,EASd,MAAM,SAAS,CAAC;AAiyBjB,wBAAsB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,EAAE,CAAC,CA2DjF;AACD,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAI1D;AACD,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAG5D;AACD,cAAc,SAAS,CAAC;AACxB,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC;AAC3B,mBAAmB,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAMR,EAAE,EAMF,WAAW,EASd,MAAM,SAAS,CAAC;AA+zBjB,wBAAsB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,EAAE,CAAC,CA+DjF;AACD,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAI1D;AACD,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAG5D;AACD,cAAc,SAAS,CAAC;AACxB,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC;AAC3B,mBAAmB,SAAS,CAAC"}
@@ -27,7 +27,15 @@ export declare function decodeIndexEntryKey(bytes: Uint8Array): DecodedIndexEntr
27
27
  export declare function indexKeyExactRange(logicalIndexKey: Uint8Array): Range;
28
28
  export declare function indexRangeToPhysicalRange(range?: Range): Range;
29
29
  export declare function extractLogicalIndexKey(def: NormalizedIndexDef, valueBytes: Uint8Array): Uint8Array | null;
30
+ /**
31
+ * Reuse the decoded document only within one synchronous mutation plan.
32
+ * Lazy decoding preserves validation order. Do not retain the extractor
33
+ * across operations or an await.
34
+ */
35
+ export declare function createIndexKeyExtractor(valueBytes: Uint8Array): (def: NormalizedIndexDef) => Uint8Array | null;
36
+ export declare function extractLogicalIndexKeyFromDocument(def: NormalizedIndexDef, documentValue: unknown): Uint8Array | null;
30
37
  export declare function serializeNormalizedIndexDefinitions(defs: ReadonlyArray<NormalizedIndexDef>): string;
31
38
  export declare function cloneNormalizedIndexDefinitions(defs: ReadonlyArray<NormalizedIndexDef>): NormalizedIndexDef[];
32
39
  export declare function toPublicIndexDefinitions(defs: ReadonlyArray<NormalizedIndexDef>): IndexDef[];
40
+ export declare function decodeIndexedDocument(bytes: Uint8Array): unknown;
33
41
  //# sourceMappingURL=indexing.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"indexing.d.ts","sourceRoot":"","sources":["../src/indexing.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAU/C,eAAO,MAAM,oBAAoB,wBAAwB,CAAC;AAC1D,MAAM,WAAW,kBAAkB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,OAAO,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;CACzB;AACD,MAAM,WAAW,oBAAoB;IACjC,UAAU,EAAE,UAAU,CAAC;IACvB,UAAU,EAAE,UAAU,CAAC;CAC1B;AACD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEzD;AACD,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAIxD;AACD,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,OAAO,GAAG,kBAAkB,EAAE,CAuD9E;AACD,wBAAgB,iCAAiC,CAAC,IAAI,EAAE,kBAAkB,EAAE,KAAK,EAAE,kBAAkB,GAAG,MAAM,CAc7G;AACD,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAE3E;AACD,wBAAgB,mBAAmB,CAC/B,IAAI,EAAE,aAAa,CAAC,kBAAkB,CAAC,EACvC,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,GACb,kBAAkB,GAAG,IAAI,CAE3B;AACD,wBAAgB,eAAe,CAAC,IAAI,EAAE,aAAa,CAAC,kBAAkB,CAAC,EAAE,KAAK,EAAE,MAAM,GAAG,kBAAkB,EAAE,CAE5G;AACD,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,UAAU,CAE9E;AACD,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,kBAAkB,GAAG,UAAU,CAE5E;AACD,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,UAAU,GAAG,kBAAkB,CAS9E;AACD,wBAAgB,mBAAmB,CAAC,eAAe,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,GAAG,UAAU,CAEnG;AACD,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,UAAU,GAAG,oBAAoB,CAS3E;AACD,wBAAgB,kBAAkB,CAAC,eAAe,EAAE,UAAU,GAAG,KAAK,CAErE;AACD,wBAAgB,yBAAyB,CAAC,KAAK,GAAE,KAAU,GAAG,KAAK,CA4BlE;AACD,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,kBAAkB,EAAE,UAAU,EAAE,UAAU,GAAG,UAAU,GAAG,IAAI,CAkBzG;AACD,wBAAgB,mCAAmC,CAAC,IAAI,EAAE,aAAa,CAAC,kBAAkB,CAAC,GAAG,MAAM,CAEnG;AACD,wBAAgB,+BAA+B,CAAC,IAAI,EAAE,aAAa,CAAC,kBAAkB,CAAC,GAAG,kBAAkB,EAAE,CAS7G;AACD,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,aAAa,CAAC,kBAAkB,CAAC,GAAG,QAAQ,EAAE,CAE5F"}
1
+ {"version":3,"file":"indexing.d.ts","sourceRoot":"","sources":["../src/indexing.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAU/C,eAAO,MAAM,oBAAoB,wBAAwB,CAAC;AAC1D,MAAM,WAAW,kBAAkB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,OAAO,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;CACzB;AACD,MAAM,WAAW,oBAAoB;IACjC,UAAU,EAAE,UAAU,CAAC;IACvB,UAAU,EAAE,UAAU,CAAC;CAC1B;AACD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEzD;AACD,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAIxD;AACD,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,OAAO,GAAG,kBAAkB,EAAE,CAuD9E;AACD,wBAAgB,iCAAiC,CAAC,IAAI,EAAE,kBAAkB,EAAE,KAAK,EAAE,kBAAkB,GAAG,MAAM,CAc7G;AACD,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAE3E;AACD,wBAAgB,mBAAmB,CAC/B,IAAI,EAAE,aAAa,CAAC,kBAAkB,CAAC,EACvC,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,GACb,kBAAkB,GAAG,IAAI,CAE3B;AACD,wBAAgB,eAAe,CAAC,IAAI,EAAE,aAAa,CAAC,kBAAkB,CAAC,EAAE,KAAK,EAAE,MAAM,GAAG,kBAAkB,EAAE,CAE5G;AACD,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,UAAU,CAE9E;AACD,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,kBAAkB,GAAG,UAAU,CAE5E;AACD,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,UAAU,GAAG,kBAAkB,CAS9E;AACD,wBAAgB,mBAAmB,CAAC,eAAe,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,GAAG,UAAU,CAEnG;AACD,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,UAAU,GAAG,oBAAoB,CAc3E;AACD,wBAAgB,kBAAkB,CAAC,eAAe,EAAE,UAAU,GAAG,KAAK,CAErE;AACD,wBAAgB,yBAAyB,CAAC,KAAK,GAAE,KAAU,GAAG,KAAK,CA4BlE;AACD,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,kBAAkB,EAAE,UAAU,EAAE,UAAU,GAAG,UAAU,GAAG,IAAI,CAEzG;AACD;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,UAAU,EAAE,UAAU,GAAG,CAAC,GAAG,EAAE,kBAAkB,KAAK,UAAU,GAAG,IAAI,CAU9G;AACD,wBAAgB,kCAAkC,CAAC,GAAG,EAAE,kBAAkB,EAAE,aAAa,EAAE,OAAO,GAAG,UAAU,GAAG,IAAI,CAiBrH;AACD,wBAAgB,mCAAmC,CAAC,IAAI,EAAE,aAAa,CAAC,kBAAkB,CAAC,GAAG,MAAM,CAEnG;AACD,wBAAgB,+BAA+B,CAAC,IAAI,EAAE,aAAa,CAAC,kBAAkB,CAAC,GAAG,kBAAkB,EAAE,CAS7G;AACD,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,aAAa,CAAC,kBAAkB,CAAC,GAAG,QAAQ,EAAE,CAE5F;AAmED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAMhE"}