@noy-db/hub 0.1.0-pre.3
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.
- package/LICENSE +21 -0
- package/README.md +197 -0
- package/dist/aggregate/index.cjs +476 -0
- package/dist/aggregate/index.cjs.map +1 -0
- package/dist/aggregate/index.d.cts +38 -0
- package/dist/aggregate/index.d.ts +38 -0
- package/dist/aggregate/index.js +53 -0
- package/dist/aggregate/index.js.map +1 -0
- package/dist/blobs/index.cjs +1480 -0
- package/dist/blobs/index.cjs.map +1 -0
- package/dist/blobs/index.d.cts +45 -0
- package/dist/blobs/index.d.ts +45 -0
- package/dist/blobs/index.js +48 -0
- package/dist/blobs/index.js.map +1 -0
- package/dist/bundle/index.cjs +436 -0
- package/dist/bundle/index.cjs.map +1 -0
- package/dist/bundle/index.d.cts +7 -0
- package/dist/bundle/index.d.ts +7 -0
- package/dist/bundle/index.js +40 -0
- package/dist/bundle/index.js.map +1 -0
- package/dist/chunk-2QR2PQTT.js +217 -0
- package/dist/chunk-2QR2PQTT.js.map +1 -0
- package/dist/chunk-4OWFYIDQ.js +79 -0
- package/dist/chunk-4OWFYIDQ.js.map +1 -0
- package/dist/chunk-5AATM2M2.js +90 -0
- package/dist/chunk-5AATM2M2.js.map +1 -0
- package/dist/chunk-ACLDOTNQ.js +543 -0
- package/dist/chunk-ACLDOTNQ.js.map +1 -0
- package/dist/chunk-BTDCBVJW.js +160 -0
- package/dist/chunk-BTDCBVJW.js.map +1 -0
- package/dist/chunk-CIMZBAZB.js +72 -0
- package/dist/chunk-CIMZBAZB.js.map +1 -0
- package/dist/chunk-E445ICYI.js +365 -0
- package/dist/chunk-E445ICYI.js.map +1 -0
- package/dist/chunk-EXQRC2L4.js +722 -0
- package/dist/chunk-EXQRC2L4.js.map +1 -0
- package/dist/chunk-FZU343FL.js +32 -0
- package/dist/chunk-FZU343FL.js.map +1 -0
- package/dist/chunk-GJILMRPO.js +354 -0
- package/dist/chunk-GJILMRPO.js.map +1 -0
- package/dist/chunk-GOUT6DND.js +1285 -0
- package/dist/chunk-GOUT6DND.js.map +1 -0
- package/dist/chunk-J66GRPNH.js +111 -0
- package/dist/chunk-J66GRPNH.js.map +1 -0
- package/dist/chunk-M2F2JAWB.js +464 -0
- package/dist/chunk-M2F2JAWB.js.map +1 -0
- package/dist/chunk-M5INGEFC.js +84 -0
- package/dist/chunk-M5INGEFC.js.map +1 -0
- package/dist/chunk-M62XNWRA.js +72 -0
- package/dist/chunk-M62XNWRA.js.map +1 -0
- package/dist/chunk-MR4424N3.js +275 -0
- package/dist/chunk-MR4424N3.js.map +1 -0
- package/dist/chunk-NPC4LFV5.js +132 -0
- package/dist/chunk-NPC4LFV5.js.map +1 -0
- package/dist/chunk-NXFEYLVG.js +311 -0
- package/dist/chunk-NXFEYLVG.js.map +1 -0
- package/dist/chunk-R36SIKES.js +79 -0
- package/dist/chunk-R36SIKES.js.map +1 -0
- package/dist/chunk-TDR6T5CJ.js +381 -0
- package/dist/chunk-TDR6T5CJ.js.map +1 -0
- package/dist/chunk-UF3BUNQZ.js +1 -0
- package/dist/chunk-UF3BUNQZ.js.map +1 -0
- package/dist/chunk-UQFSPSWG.js +1109 -0
- package/dist/chunk-UQFSPSWG.js.map +1 -0
- package/dist/chunk-USKYUS74.js +793 -0
- package/dist/chunk-USKYUS74.js.map +1 -0
- package/dist/chunk-XCL3WP6J.js +121 -0
- package/dist/chunk-XCL3WP6J.js.map +1 -0
- package/dist/chunk-XHFOENR2.js +680 -0
- package/dist/chunk-XHFOENR2.js.map +1 -0
- package/dist/chunk-ZFKD4QMV.js +430 -0
- package/dist/chunk-ZFKD4QMV.js.map +1 -0
- package/dist/chunk-ZLMV3TUA.js +490 -0
- package/dist/chunk-ZLMV3TUA.js.map +1 -0
- package/dist/chunk-ZRG4V3F5.js +17 -0
- package/dist/chunk-ZRG4V3F5.js.map +1 -0
- package/dist/consent/index.cjs +204 -0
- package/dist/consent/index.cjs.map +1 -0
- package/dist/consent/index.d.cts +24 -0
- package/dist/consent/index.d.ts +24 -0
- package/dist/consent/index.js +23 -0
- package/dist/consent/index.js.map +1 -0
- package/dist/crdt/index.cjs +152 -0
- package/dist/crdt/index.cjs.map +1 -0
- package/dist/crdt/index.d.cts +30 -0
- package/dist/crdt/index.d.ts +30 -0
- package/dist/crdt/index.js +24 -0
- package/dist/crdt/index.js.map +1 -0
- package/dist/crypto-IVKU7YTT.js +44 -0
- package/dist/crypto-IVKU7YTT.js.map +1 -0
- package/dist/delegation-XDJCBTI2.js +16 -0
- package/dist/delegation-XDJCBTI2.js.map +1 -0
- package/dist/dev-unlock-CeXic1xC.d.cts +263 -0
- package/dist/dev-unlock-KrKkcqD3.d.ts +263 -0
- package/dist/hash-9KO1BGxh.d.cts +63 -0
- package/dist/hash-ChfJjRjQ.d.ts +63 -0
- package/dist/history/index.cjs +1215 -0
- package/dist/history/index.cjs.map +1 -0
- package/dist/history/index.d.cts +62 -0
- package/dist/history/index.d.ts +62 -0
- package/dist/history/index.js +79 -0
- package/dist/history/index.js.map +1 -0
- package/dist/i18n/index.cjs +746 -0
- package/dist/i18n/index.cjs.map +1 -0
- package/dist/i18n/index.d.cts +38 -0
- package/dist/i18n/index.d.ts +38 -0
- package/dist/i18n/index.js +55 -0
- package/dist/i18n/index.js.map +1 -0
- package/dist/index-BRHBCmLt.d.ts +1940 -0
- package/dist/index-C8kQtmOk.d.ts +380 -0
- package/dist/index-DN-J-5wT.d.cts +1940 -0
- package/dist/index-DhjMjz7L.d.cts +380 -0
- package/dist/index.cjs +14756 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +269 -0
- package/dist/index.d.ts +269 -0
- package/dist/index.js +6085 -0
- package/dist/index.js.map +1 -0
- package/dist/indexing/index.cjs +736 -0
- package/dist/indexing/index.cjs.map +1 -0
- package/dist/indexing/index.d.cts +36 -0
- package/dist/indexing/index.d.ts +36 -0
- package/dist/indexing/index.js +77 -0
- package/dist/indexing/index.js.map +1 -0
- package/dist/lazy-builder-BwEoBQZ9.d.ts +304 -0
- package/dist/lazy-builder-CZVLKh0Z.d.cts +304 -0
- package/dist/ledger-2NX4L7PN.js +33 -0
- package/dist/ledger-2NX4L7PN.js.map +1 -0
- package/dist/mime-magic-CBBSOkjm.d.cts +50 -0
- package/dist/mime-magic-CBBSOkjm.d.ts +50 -0
- package/dist/periods/index.cjs +1035 -0
- package/dist/periods/index.cjs.map +1 -0
- package/dist/periods/index.d.cts +21 -0
- package/dist/periods/index.d.ts +21 -0
- package/dist/periods/index.js +25 -0
- package/dist/periods/index.js.map +1 -0
- package/dist/predicate-SBHmi6D0.d.cts +161 -0
- package/dist/predicate-SBHmi6D0.d.ts +161 -0
- package/dist/query/index.cjs +1957 -0
- package/dist/query/index.cjs.map +1 -0
- package/dist/query/index.d.cts +3 -0
- package/dist/query/index.d.ts +3 -0
- package/dist/query/index.js +62 -0
- package/dist/query/index.js.map +1 -0
- package/dist/session/index.cjs +487 -0
- package/dist/session/index.cjs.map +1 -0
- package/dist/session/index.d.cts +45 -0
- package/dist/session/index.d.ts +45 -0
- package/dist/session/index.js +44 -0
- package/dist/session/index.js.map +1 -0
- package/dist/shadow/index.cjs +133 -0
- package/dist/shadow/index.cjs.map +1 -0
- package/dist/shadow/index.d.cts +16 -0
- package/dist/shadow/index.d.ts +16 -0
- package/dist/shadow/index.js +20 -0
- package/dist/shadow/index.js.map +1 -0
- package/dist/store/index.cjs +1069 -0
- package/dist/store/index.cjs.map +1 -0
- package/dist/store/index.d.cts +491 -0
- package/dist/store/index.d.ts +491 -0
- package/dist/store/index.js +34 -0
- package/dist/store/index.js.map +1 -0
- package/dist/strategy-BSxFXGzb.d.cts +110 -0
- package/dist/strategy-BSxFXGzb.d.ts +110 -0
- package/dist/strategy-D-SrOLCl.d.cts +548 -0
- package/dist/strategy-D-SrOLCl.d.ts +548 -0
- package/dist/sync/index.cjs +1062 -0
- package/dist/sync/index.cjs.map +1 -0
- package/dist/sync/index.d.cts +42 -0
- package/dist/sync/index.d.ts +42 -0
- package/dist/sync/index.js +28 -0
- package/dist/sync/index.js.map +1 -0
- package/dist/team/index.cjs +1233 -0
- package/dist/team/index.cjs.map +1 -0
- package/dist/team/index.d.cts +117 -0
- package/dist/team/index.d.ts +117 -0
- package/dist/team/index.js +39 -0
- package/dist/team/index.js.map +1 -0
- package/dist/tx/index.cjs +212 -0
- package/dist/tx/index.cjs.map +1 -0
- package/dist/tx/index.d.cts +20 -0
- package/dist/tx/index.d.ts +20 -0
- package/dist/tx/index.js +20 -0
- package/dist/tx/index.js.map +1 -0
- package/dist/types-BZpCZB8N.d.ts +7526 -0
- package/dist/types-Bfs0qr5F.d.cts +7526 -0
- package/dist/ulid-COREQ2RQ.js +9 -0
- package/dist/ulid-COREQ2RQ.js.map +1 -0
- package/dist/util/index.cjs +230 -0
- package/dist/util/index.cjs.map +1 -0
- package/dist/util/index.d.cts +77 -0
- package/dist/util/index.d.ts +77 -0
- package/dist/util/index.js +190 -0
- package/dist/util/index.js.map +1 -0
- package/package.json +244 -0
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { B as BlobStrategy } from '../types-Bfs0qr5F.cjs';
|
|
2
|
+
export { p as BLOB_CHUNKS_COLLECTION, q as BLOB_COLLECTION, s as BLOB_EVICTION_AUDIT_COLLECTION, t as BLOB_INDEX_COLLECTION, u as BLOB_SLOTS_PREFIX, w as BLOB_VERSIONS_PREFIX, x as BlobEvictionEntry, y as BlobFieldPolicy, z as BlobFieldsConfig, A as BlobObject, C as BlobPutOptions, E as BlobResponseOptions, F as BlobSet, G as BlobStrategyOpenArgs, H as CompactRunOptions, J as CompactionContext, K as CompactionResult, L as DEFAULT_CHUNK_SIZE, M as EXPORT_AUDIT_COLLECTION, N as ExportBlobsAbortedError, O as ExportBlobsAuditEntry, Q as ExportBlobsHandle, R as ExportBlobsOptions, T as ExportedBlob, U as SlotInfo, V as SlotRecord, W as VersionRecord, X as createExportBlobsHandle, Y as runCompaction } from '../types-Bfs0qr5F.cjs';
|
|
3
|
+
export { d as detectMagic, a as detectMimeType, i as isPreCompressed } from '../mime-magic-CBBSOkjm.cjs';
|
|
4
|
+
import '../lazy-builder-CZVLKh0Z.cjs';
|
|
5
|
+
import '../predicate-SBHmi6D0.cjs';
|
|
6
|
+
import '../strategy-D-SrOLCl.cjs';
|
|
7
|
+
import '../strategy-BSxFXGzb.cjs';
|
|
8
|
+
import '../index-DN-J-5wT.cjs';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Active blob strategy factory. Calling `blobs()` returns a
|
|
12
|
+
* `BlobStrategy` whose `openSlot` constructs a real `BlobSet` bound
|
|
13
|
+
* to the caller's record. The returned strategy is passed into
|
|
14
|
+
* `createNoydb({ blobStrategy: blobs() })` to light up the
|
|
15
|
+
* `collection.blob(id)` path.
|
|
16
|
+
*
|
|
17
|
+
* This module is only reachable through the `@noy-db/hub/blobs`
|
|
18
|
+
* subpath — a consumer that never imports the subpath ships none of
|
|
19
|
+
* this (ESM tree-shaking + hub's `"sideEffects": false`).
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Build a default `BlobStrategy` ready to pass into `createNoydb`.
|
|
24
|
+
*
|
|
25
|
+
* Named `withBlobs` (plugin-pattern canonical) rather than `blobs` to
|
|
26
|
+
* avoid shadowing the very common local idiom
|
|
27
|
+
* `const blobs = invoices.blob(id)` in user code.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```ts
|
|
31
|
+
* import { createNoydb } from '@noy-db/hub'
|
|
32
|
+
* import { withBlobs } from '@noy-db/hub/blobs'
|
|
33
|
+
*
|
|
34
|
+
* const db = await createNoydb({
|
|
35
|
+
* store, user, secret,
|
|
36
|
+
* blobStrategy: withBlobs(),
|
|
37
|
+
* })
|
|
38
|
+
*
|
|
39
|
+
* // Now live — delegates to BlobSet.
|
|
40
|
+
* await db.vault('acme').collection('invoices').blob('inv-1').put('receipt.pdf', bytes)
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
declare function withBlobs(): BlobStrategy;
|
|
44
|
+
|
|
45
|
+
export { BlobStrategy, withBlobs };
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { B as BlobStrategy } from '../types-BZpCZB8N.js';
|
|
2
|
+
export { p as BLOB_CHUNKS_COLLECTION, q as BLOB_COLLECTION, s as BLOB_EVICTION_AUDIT_COLLECTION, t as BLOB_INDEX_COLLECTION, u as BLOB_SLOTS_PREFIX, w as BLOB_VERSIONS_PREFIX, x as BlobEvictionEntry, y as BlobFieldPolicy, z as BlobFieldsConfig, A as BlobObject, C as BlobPutOptions, E as BlobResponseOptions, F as BlobSet, G as BlobStrategyOpenArgs, H as CompactRunOptions, J as CompactionContext, K as CompactionResult, L as DEFAULT_CHUNK_SIZE, M as EXPORT_AUDIT_COLLECTION, N as ExportBlobsAbortedError, O as ExportBlobsAuditEntry, Q as ExportBlobsHandle, R as ExportBlobsOptions, T as ExportedBlob, U as SlotInfo, V as SlotRecord, W as VersionRecord, X as createExportBlobsHandle, Y as runCompaction } from '../types-BZpCZB8N.js';
|
|
3
|
+
export { d as detectMagic, a as detectMimeType, i as isPreCompressed } from '../mime-magic-CBBSOkjm.js';
|
|
4
|
+
import '../lazy-builder-BwEoBQZ9.js';
|
|
5
|
+
import '../predicate-SBHmi6D0.js';
|
|
6
|
+
import '../strategy-D-SrOLCl.js';
|
|
7
|
+
import '../strategy-BSxFXGzb.js';
|
|
8
|
+
import '../index-BRHBCmLt.js';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Active blob strategy factory. Calling `blobs()` returns a
|
|
12
|
+
* `BlobStrategy` whose `openSlot` constructs a real `BlobSet` bound
|
|
13
|
+
* to the caller's record. The returned strategy is passed into
|
|
14
|
+
* `createNoydb({ blobStrategy: blobs() })` to light up the
|
|
15
|
+
* `collection.blob(id)` path.
|
|
16
|
+
*
|
|
17
|
+
* This module is only reachable through the `@noy-db/hub/blobs`
|
|
18
|
+
* subpath — a consumer that never imports the subpath ships none of
|
|
19
|
+
* this (ESM tree-shaking + hub's `"sideEffects": false`).
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Build a default `BlobStrategy` ready to pass into `createNoydb`.
|
|
24
|
+
*
|
|
25
|
+
* Named `withBlobs` (plugin-pattern canonical) rather than `blobs` to
|
|
26
|
+
* avoid shadowing the very common local idiom
|
|
27
|
+
* `const blobs = invoices.blob(id)` in user code.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```ts
|
|
31
|
+
* import { createNoydb } from '@noy-db/hub'
|
|
32
|
+
* import { withBlobs } from '@noy-db/hub/blobs'
|
|
33
|
+
*
|
|
34
|
+
* const db = await createNoydb({
|
|
35
|
+
* store, user, secret,
|
|
36
|
+
* blobStrategy: withBlobs(),
|
|
37
|
+
* })
|
|
38
|
+
*
|
|
39
|
+
* // Now live — delegates to BlobSet.
|
|
40
|
+
* await db.vault('acme').collection('invoices').blob('inv-1').put('receipt.pdf', bytes)
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
declare function withBlobs(): BlobStrategy;
|
|
44
|
+
|
|
45
|
+
export { BlobStrategy, withBlobs };
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BLOB_CHUNKS_COLLECTION,
|
|
3
|
+
BLOB_COLLECTION,
|
|
4
|
+
BLOB_EVICTION_AUDIT_COLLECTION,
|
|
5
|
+
BLOB_INDEX_COLLECTION,
|
|
6
|
+
BLOB_SLOTS_PREFIX,
|
|
7
|
+
BLOB_VERSIONS_PREFIX,
|
|
8
|
+
BlobSet,
|
|
9
|
+
DEFAULT_CHUNK_SIZE,
|
|
10
|
+
EXPORT_AUDIT_COLLECTION,
|
|
11
|
+
ExportBlobsAbortedError,
|
|
12
|
+
createExportBlobsHandle,
|
|
13
|
+
detectMagic,
|
|
14
|
+
detectMimeType,
|
|
15
|
+
isPreCompressed,
|
|
16
|
+
runCompaction
|
|
17
|
+
} from "../chunk-UQFSPSWG.js";
|
|
18
|
+
import "../chunk-ZRG4V3F5.js";
|
|
19
|
+
import "../chunk-MR4424N3.js";
|
|
20
|
+
import "../chunk-ACLDOTNQ.js";
|
|
21
|
+
|
|
22
|
+
// src/blobs/active.ts
|
|
23
|
+
function withBlobs() {
|
|
24
|
+
return {
|
|
25
|
+
openSlot(args) {
|
|
26
|
+
return new BlobSet(args);
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
export {
|
|
31
|
+
BLOB_CHUNKS_COLLECTION,
|
|
32
|
+
BLOB_COLLECTION,
|
|
33
|
+
BLOB_EVICTION_AUDIT_COLLECTION,
|
|
34
|
+
BLOB_INDEX_COLLECTION,
|
|
35
|
+
BLOB_SLOTS_PREFIX,
|
|
36
|
+
BLOB_VERSIONS_PREFIX,
|
|
37
|
+
BlobSet,
|
|
38
|
+
DEFAULT_CHUNK_SIZE,
|
|
39
|
+
EXPORT_AUDIT_COLLECTION,
|
|
40
|
+
ExportBlobsAbortedError,
|
|
41
|
+
createExportBlobsHandle,
|
|
42
|
+
detectMagic,
|
|
43
|
+
detectMimeType,
|
|
44
|
+
isPreCompressed,
|
|
45
|
+
runCompaction,
|
|
46
|
+
withBlobs
|
|
47
|
+
};
|
|
48
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/blobs/active.ts"],"sourcesContent":["/**\n * Active blob strategy factory. Calling `blobs()` returns a\n * `BlobStrategy` whose `openSlot` constructs a real `BlobSet` bound\n * to the caller's record. The returned strategy is passed into\n * `createNoydb({ blobStrategy: blobs() })` to light up the\n * `collection.blob(id)` path.\n *\n * This module is only reachable through the `@noy-db/hub/blobs`\n * subpath — a consumer that never imports the subpath ships none of\n * this (ESM tree-shaking + hub's `\"sideEffects\": false`).\n */\n\nimport { BlobSet } from './blob-set.js'\nimport type { BlobStrategy } from './strategy.js'\n\n/**\n * Build a default `BlobStrategy` ready to pass into `createNoydb`.\n *\n * Named `withBlobs` (plugin-pattern canonical) rather than `blobs` to\n * avoid shadowing the very common local idiom\n * `const blobs = invoices.blob(id)` in user code.\n *\n * @example\n * ```ts\n * import { createNoydb } from '@noy-db/hub'\n * import { withBlobs } from '@noy-db/hub/blobs'\n *\n * const db = await createNoydb({\n * store, user, secret,\n * blobStrategy: withBlobs(),\n * })\n *\n * // Now live — delegates to BlobSet.\n * await db.vault('acme').collection('invoices').blob('inv-1').put('receipt.pdf', bytes)\n * ```\n */\nexport function withBlobs(): BlobStrategy {\n return {\n openSlot(args) {\n return new BlobSet(args)\n },\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAoCO,SAAS,YAA0B;AACxC,SAAO;AAAA,IACL,SAAS,MAAM;AACb,aAAO,IAAI,QAAQ,IAAI;AAAA,IACzB;AAAA,EACF;AACF;","names":[]}
|
|
@@ -0,0 +1,436 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/bundle/index.ts
|
|
21
|
+
var bundle_exports = {};
|
|
22
|
+
__export(bundle_exports, {
|
|
23
|
+
COMPRESSION_BROTLI: () => COMPRESSION_BROTLI,
|
|
24
|
+
COMPRESSION_GZIP: () => COMPRESSION_GZIP,
|
|
25
|
+
COMPRESSION_NONE: () => COMPRESSION_NONE,
|
|
26
|
+
FLAG_COMPRESSED: () => FLAG_COMPRESSED,
|
|
27
|
+
FLAG_HAS_INTEGRITY_HASH: () => FLAG_HAS_INTEGRITY_HASH,
|
|
28
|
+
NOYDB_BUNDLE_FORMAT_VERSION: () => NOYDB_BUNDLE_FORMAT_VERSION,
|
|
29
|
+
NOYDB_BUNDLE_MAGIC: () => NOYDB_BUNDLE_MAGIC,
|
|
30
|
+
NOYDB_BUNDLE_PREFIX_BYTES: () => NOYDB_BUNDLE_PREFIX_BYTES,
|
|
31
|
+
encodeBundleHeader: () => encodeBundleHeader,
|
|
32
|
+
generateULID: () => generateULID,
|
|
33
|
+
isULID: () => isULID,
|
|
34
|
+
readNoydbBundle: () => readNoydbBundle,
|
|
35
|
+
readNoydbBundleHeader: () => readNoydbBundleHeader,
|
|
36
|
+
resetBrotliSupportCache: () => resetBrotliSupportCache,
|
|
37
|
+
validateBundleHeader: () => validateBundleHeader,
|
|
38
|
+
writeNoydbBundle: () => writeNoydbBundle
|
|
39
|
+
});
|
|
40
|
+
module.exports = __toCommonJS(bundle_exports);
|
|
41
|
+
|
|
42
|
+
// src/bundle/format.ts
|
|
43
|
+
var NOYDB_BUNDLE_MAGIC = new Uint8Array([78, 68, 66, 49]);
|
|
44
|
+
var NOYDB_BUNDLE_PREFIX_BYTES = 10;
|
|
45
|
+
var NOYDB_BUNDLE_FORMAT_VERSION = 1;
|
|
46
|
+
var FLAG_COMPRESSED = 1;
|
|
47
|
+
var FLAG_HAS_INTEGRITY_HASH = 2;
|
|
48
|
+
var COMPRESSION_NONE = 0;
|
|
49
|
+
var COMPRESSION_GZIP = 1;
|
|
50
|
+
var COMPRESSION_BROTLI = 2;
|
|
51
|
+
var ALLOWED_HEADER_KEYS = /* @__PURE__ */ new Set([
|
|
52
|
+
"formatVersion",
|
|
53
|
+
"handle",
|
|
54
|
+
"bodyBytes",
|
|
55
|
+
"bodySha256"
|
|
56
|
+
]);
|
|
57
|
+
function validateBundleHeader(parsed) {
|
|
58
|
+
if (parsed === null || typeof parsed !== "object") {
|
|
59
|
+
throw new Error(
|
|
60
|
+
`.noydb bundle header must be a JSON object, got ${parsed === null ? "null" : typeof parsed}`
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
for (const key of Object.keys(parsed)) {
|
|
64
|
+
if (!ALLOWED_HEADER_KEYS.has(key)) {
|
|
65
|
+
throw new Error(
|
|
66
|
+
`.noydb bundle header contains forbidden key "${key}". Only minimum-disclosure fields are allowed: ${[...ALLOWED_HEADER_KEYS].join(", ")}.`
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
const h = parsed;
|
|
71
|
+
if (typeof h["formatVersion"] !== "number" || h["formatVersion"] !== NOYDB_BUNDLE_FORMAT_VERSION) {
|
|
72
|
+
throw new Error(
|
|
73
|
+
`.noydb bundle header.formatVersion must be ${NOYDB_BUNDLE_FORMAT_VERSION}, got ${String(h["formatVersion"])}. The reader does not support forward-compat versions; upgrade the reader to handle newer bundles.`
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
if (typeof h["handle"] !== "string" || !/^[0-9A-HJKMNP-TV-Z]{26}$/.test(h["handle"])) {
|
|
77
|
+
throw new Error(
|
|
78
|
+
`.noydb bundle header.handle must be a 26-character Crockford base32 ULID, got ${typeof h["handle"] === "string" ? `"${h["handle"]}"` : String(h["handle"])}.`
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
if (typeof h["bodyBytes"] !== "number" || !Number.isInteger(h["bodyBytes"]) || h["bodyBytes"] < 0) {
|
|
82
|
+
throw new Error(
|
|
83
|
+
`.noydb bundle header.bodyBytes must be a non-negative integer, got ${String(h["bodyBytes"])}.`
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
if (typeof h["bodySha256"] !== "string" || !/^[0-9a-f]{64}$/.test(h["bodySha256"])) {
|
|
87
|
+
throw new Error(
|
|
88
|
+
`.noydb bundle header.bodySha256 must be a 64-character lowercase hex string, got ${typeof h["bodySha256"] === "string" ? `"${h["bodySha256"]}"` : String(h["bodySha256"])}.`
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
function encodeBundleHeader(header) {
|
|
93
|
+
validateBundleHeader(header);
|
|
94
|
+
const json = JSON.stringify({
|
|
95
|
+
formatVersion: header.formatVersion,
|
|
96
|
+
handle: header.handle,
|
|
97
|
+
bodyBytes: header.bodyBytes,
|
|
98
|
+
bodySha256: header.bodySha256
|
|
99
|
+
});
|
|
100
|
+
return new TextEncoder().encode(json);
|
|
101
|
+
}
|
|
102
|
+
function decodeBundleHeader(bytes) {
|
|
103
|
+
const json = new TextDecoder("utf-8", { fatal: true }).decode(bytes);
|
|
104
|
+
let parsed;
|
|
105
|
+
try {
|
|
106
|
+
parsed = JSON.parse(json);
|
|
107
|
+
} catch (err) {
|
|
108
|
+
throw new Error(
|
|
109
|
+
`.noydb bundle header is not valid JSON: ${err.message}`
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
validateBundleHeader(parsed);
|
|
113
|
+
return parsed;
|
|
114
|
+
}
|
|
115
|
+
function readUint32BE(bytes, offset) {
|
|
116
|
+
return (bytes[offset] << 24 >>> 0) + (bytes[offset + 1] << 16) + (bytes[offset + 2] << 8) + bytes[offset + 3];
|
|
117
|
+
}
|
|
118
|
+
function writeUint32BE(bytes, offset, value) {
|
|
119
|
+
bytes[offset] = value >>> 24 & 255;
|
|
120
|
+
bytes[offset + 1] = value >>> 16 & 255;
|
|
121
|
+
bytes[offset + 2] = value >>> 8 & 255;
|
|
122
|
+
bytes[offset + 3] = value & 255;
|
|
123
|
+
}
|
|
124
|
+
function hasNoydbBundleMagic(bytes) {
|
|
125
|
+
if (bytes.length < NOYDB_BUNDLE_MAGIC.length) return false;
|
|
126
|
+
for (let i = 0; i < NOYDB_BUNDLE_MAGIC.length; i++) {
|
|
127
|
+
if (bytes[i] !== NOYDB_BUNDLE_MAGIC[i]) return false;
|
|
128
|
+
}
|
|
129
|
+
return true;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// src/errors.ts
|
|
133
|
+
var NoydbError = class extends Error {
|
|
134
|
+
/** Machine-readable error code. Stable across library versions. */
|
|
135
|
+
code;
|
|
136
|
+
constructor(code, message) {
|
|
137
|
+
super(message);
|
|
138
|
+
this.name = "NoydbError";
|
|
139
|
+
this.code = code;
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
var BundleIntegrityError = class extends NoydbError {
|
|
143
|
+
constructor(message) {
|
|
144
|
+
super("BUNDLE_INTEGRITY", `.noydb bundle integrity check failed: ${message}`);
|
|
145
|
+
this.name = "BundleIntegrityError";
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
// src/bundle/bundle.ts
|
|
150
|
+
var cachedBrotliSupport = null;
|
|
151
|
+
function supportsBrotliCompression() {
|
|
152
|
+
if (cachedBrotliSupport !== null) return cachedBrotliSupport;
|
|
153
|
+
try {
|
|
154
|
+
new CompressionStream("br");
|
|
155
|
+
cachedBrotliSupport = true;
|
|
156
|
+
} catch {
|
|
157
|
+
cachedBrotliSupport = false;
|
|
158
|
+
}
|
|
159
|
+
return cachedBrotliSupport;
|
|
160
|
+
}
|
|
161
|
+
function resetBrotliSupportCache() {
|
|
162
|
+
cachedBrotliSupport = null;
|
|
163
|
+
}
|
|
164
|
+
function selectCompression(option) {
|
|
165
|
+
const choice = option ?? "auto";
|
|
166
|
+
if (choice === "none") return { format: COMPRESSION_NONE, streamFormat: null };
|
|
167
|
+
if (choice === "gzip") return { format: COMPRESSION_GZIP, streamFormat: "gzip" };
|
|
168
|
+
if (choice === "brotli") {
|
|
169
|
+
if (!supportsBrotliCompression()) {
|
|
170
|
+
throw new Error(
|
|
171
|
+
`writeNoydbBundle({ compression: 'brotli' }) is not supported on this runtime. Brotli requires Node 22+, Chrome 124+, or Firefox 122+. Use { compression: 'auto' } to fall back to gzip silently, or { compression: 'gzip' } to be explicit.`
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
return { format: COMPRESSION_BROTLI, streamFormat: "br" };
|
|
175
|
+
}
|
|
176
|
+
if (supportsBrotliCompression()) {
|
|
177
|
+
return { format: COMPRESSION_BROTLI, streamFormat: "br" };
|
|
178
|
+
}
|
|
179
|
+
return { format: COMPRESSION_GZIP, streamFormat: "gzip" };
|
|
180
|
+
}
|
|
181
|
+
async function pumpThroughStream(input, stream) {
|
|
182
|
+
const readable = new Blob([input]).stream().pipeThrough(stream);
|
|
183
|
+
const reader = readable.getReader();
|
|
184
|
+
const chunks = [];
|
|
185
|
+
let total = 0;
|
|
186
|
+
for (; ; ) {
|
|
187
|
+
const { value, done } = await reader.read();
|
|
188
|
+
if (done) break;
|
|
189
|
+
if (value) {
|
|
190
|
+
chunks.push(value);
|
|
191
|
+
total += value.length;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
const out = new Uint8Array(total);
|
|
195
|
+
let offset = 0;
|
|
196
|
+
for (const chunk of chunks) {
|
|
197
|
+
out.set(chunk, offset);
|
|
198
|
+
offset += chunk.length;
|
|
199
|
+
}
|
|
200
|
+
return out;
|
|
201
|
+
}
|
|
202
|
+
async function sha256Hex(bytes) {
|
|
203
|
+
const copy = new Uint8Array(bytes.length);
|
|
204
|
+
copy.set(bytes);
|
|
205
|
+
const digest = await crypto.subtle.digest("SHA-256", copy);
|
|
206
|
+
const view = new Uint8Array(digest);
|
|
207
|
+
let hex = "";
|
|
208
|
+
for (let i = 0; i < view.length; i++) {
|
|
209
|
+
hex += view[i].toString(16).padStart(2, "0");
|
|
210
|
+
}
|
|
211
|
+
return hex;
|
|
212
|
+
}
|
|
213
|
+
function concatBytes(parts) {
|
|
214
|
+
let total = 0;
|
|
215
|
+
for (const p of parts) total += p.length;
|
|
216
|
+
const out = new Uint8Array(total);
|
|
217
|
+
let offset = 0;
|
|
218
|
+
for (const p of parts) {
|
|
219
|
+
out.set(p, offset);
|
|
220
|
+
offset += p.length;
|
|
221
|
+
}
|
|
222
|
+
return out;
|
|
223
|
+
}
|
|
224
|
+
async function applyRecipientRewrap(vault, dumpJson, opts) {
|
|
225
|
+
if (opts.exportPassphrase === void 0 && opts.recipients === void 0) {
|
|
226
|
+
return dumpJson;
|
|
227
|
+
}
|
|
228
|
+
const recipients = opts.recipients ?? [
|
|
229
|
+
{
|
|
230
|
+
id: vault.userId,
|
|
231
|
+
passphrase: opts.exportPassphrase,
|
|
232
|
+
role: vault.role
|
|
233
|
+
}
|
|
234
|
+
];
|
|
235
|
+
const recipientKeyrings = await vault.buildBundleRecipientKeyrings(recipients);
|
|
236
|
+
const backup = JSON.parse(dumpJson);
|
|
237
|
+
backup.keyrings = recipientKeyrings;
|
|
238
|
+
return JSON.stringify(backup);
|
|
239
|
+
}
|
|
240
|
+
function applySliceFilters(dumpJson, opts) {
|
|
241
|
+
const collectionsFilter = opts.collections ? new Set(opts.collections) : null;
|
|
242
|
+
const sinceMs = opts.since !== void 0 ? new Date(opts.since).getTime() : null;
|
|
243
|
+
if (collectionsFilter === null && sinceMs === null) return dumpJson;
|
|
244
|
+
const backup = JSON.parse(dumpJson);
|
|
245
|
+
if (backup.collections && typeof backup.collections === "object") {
|
|
246
|
+
const next = {};
|
|
247
|
+
for (const [name, records] of Object.entries(backup.collections)) {
|
|
248
|
+
if (collectionsFilter && !collectionsFilter.has(name)) continue;
|
|
249
|
+
if (sinceMs === null) {
|
|
250
|
+
next[name] = records;
|
|
251
|
+
continue;
|
|
252
|
+
}
|
|
253
|
+
const kept = {};
|
|
254
|
+
for (const [id, env] of Object.entries(records)) {
|
|
255
|
+
const envTs = env._ts ? new Date(env._ts).getTime() : NaN;
|
|
256
|
+
if (Number.isFinite(envTs) && envTs >= sinceMs) {
|
|
257
|
+
kept[id] = env;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
next[name] = kept;
|
|
261
|
+
}
|
|
262
|
+
backup.collections = next;
|
|
263
|
+
}
|
|
264
|
+
return JSON.stringify(backup);
|
|
265
|
+
}
|
|
266
|
+
async function applyPlaintextFilters(vault, dumpJson, opts) {
|
|
267
|
+
if (opts.where === void 0 && opts.tierAtMost === void 0) {
|
|
268
|
+
return dumpJson;
|
|
269
|
+
}
|
|
270
|
+
const backup = JSON.parse(dumpJson);
|
|
271
|
+
if (!backup.collections || typeof backup.collections !== "object") {
|
|
272
|
+
return dumpJson;
|
|
273
|
+
}
|
|
274
|
+
const tierCeiling = opts.tierAtMost;
|
|
275
|
+
const where = opts.where;
|
|
276
|
+
const next = {};
|
|
277
|
+
for (const [collName, records] of Object.entries(backup.collections)) {
|
|
278
|
+
const kept = {};
|
|
279
|
+
for (const [id, env] of Object.entries(records)) {
|
|
280
|
+
if (tierCeiling !== void 0) {
|
|
281
|
+
const tier = env._tier ?? 0;
|
|
282
|
+
if (tier > tierCeiling) continue;
|
|
283
|
+
}
|
|
284
|
+
if (where !== void 0) {
|
|
285
|
+
const record = await vault._decryptEnvelopeForBundleFilter(
|
|
286
|
+
env,
|
|
287
|
+
collName
|
|
288
|
+
);
|
|
289
|
+
const ok = await where(record, { collection: collName, id });
|
|
290
|
+
if (!ok) continue;
|
|
291
|
+
}
|
|
292
|
+
kept[id] = env;
|
|
293
|
+
}
|
|
294
|
+
next[collName] = kept;
|
|
295
|
+
}
|
|
296
|
+
backup.collections = next;
|
|
297
|
+
return JSON.stringify(backup);
|
|
298
|
+
}
|
|
299
|
+
async function writeNoydbBundle(vault, opts = {}) {
|
|
300
|
+
if (opts.exportPassphrase !== void 0 && opts.recipients !== void 0) {
|
|
301
|
+
throw new Error(
|
|
302
|
+
"writeNoydbBundle: pass either exportPassphrase or recipients, not both"
|
|
303
|
+
);
|
|
304
|
+
}
|
|
305
|
+
const handle = await vault.getBundleHandle();
|
|
306
|
+
const dumpJson = await vault.dump();
|
|
307
|
+
const rekeyed = await applyRecipientRewrap(vault, dumpJson, opts);
|
|
308
|
+
const plainFiltered = await applyPlaintextFilters(vault, rekeyed, opts);
|
|
309
|
+
const filtered = applySliceFilters(plainFiltered, opts);
|
|
310
|
+
const dumpBytes = new TextEncoder().encode(filtered);
|
|
311
|
+
const { format, streamFormat } = selectCompression(opts.compression);
|
|
312
|
+
const body = streamFormat === null ? dumpBytes : await pumpThroughStream(dumpBytes, new CompressionStream(streamFormat));
|
|
313
|
+
const bodySha256 = await sha256Hex(body);
|
|
314
|
+
const header = {
|
|
315
|
+
formatVersion: NOYDB_BUNDLE_FORMAT_VERSION,
|
|
316
|
+
handle,
|
|
317
|
+
bodyBytes: body.length,
|
|
318
|
+
bodySha256
|
|
319
|
+
};
|
|
320
|
+
const headerBytes = encodeBundleHeader(header);
|
|
321
|
+
const prefix = new Uint8Array(NOYDB_BUNDLE_PREFIX_BYTES);
|
|
322
|
+
prefix.set(NOYDB_BUNDLE_MAGIC, 0);
|
|
323
|
+
prefix[4] = (streamFormat === null ? 0 : FLAG_COMPRESSED) | FLAG_HAS_INTEGRITY_HASH;
|
|
324
|
+
prefix[5] = format;
|
|
325
|
+
writeUint32BE(prefix, 6, headerBytes.length);
|
|
326
|
+
return concatBytes([prefix, headerBytes, body]);
|
|
327
|
+
}
|
|
328
|
+
function parsePrefixAndHeader(bytes) {
|
|
329
|
+
if (!hasNoydbBundleMagic(bytes)) {
|
|
330
|
+
throw new Error(
|
|
331
|
+
`Not a .noydb bundle: missing 'NDB1' magic prefix. The first 4 bytes are ${[...bytes.slice(0, 4)].map((b) => b.toString(16).padStart(2, "0")).join(" ")}.`
|
|
332
|
+
);
|
|
333
|
+
}
|
|
334
|
+
if (bytes.length < NOYDB_BUNDLE_PREFIX_BYTES) {
|
|
335
|
+
throw new Error(
|
|
336
|
+
`Truncated .noydb bundle: file is only ${bytes.length} bytes, which is less than the ${NOYDB_BUNDLE_PREFIX_BYTES}-byte fixed prefix.`
|
|
337
|
+
);
|
|
338
|
+
}
|
|
339
|
+
const flags = bytes[4];
|
|
340
|
+
const algo = bytes[5];
|
|
341
|
+
if (algo !== COMPRESSION_NONE && algo !== COMPRESSION_GZIP && algo !== COMPRESSION_BROTLI) {
|
|
342
|
+
throw new Error(
|
|
343
|
+
`.noydb bundle declares unknown compression algorithm ${algo}. Known values: 0 (none), 1 (gzip), 2 (brotli).`
|
|
344
|
+
);
|
|
345
|
+
}
|
|
346
|
+
const headerLength = readUint32BE(bytes, 6);
|
|
347
|
+
const bodyOffset = NOYDB_BUNDLE_PREFIX_BYTES + headerLength;
|
|
348
|
+
if (bodyOffset > bytes.length) {
|
|
349
|
+
throw new Error(
|
|
350
|
+
`Truncated .noydb bundle: declared header length ${headerLength} would extend past end of file (${bytes.length} bytes).`
|
|
351
|
+
);
|
|
352
|
+
}
|
|
353
|
+
const headerBytes = bytes.slice(NOYDB_BUNDLE_PREFIX_BYTES, bodyOffset);
|
|
354
|
+
const header = decodeBundleHeader(headerBytes);
|
|
355
|
+
return { header, bodyOffset, algo, flags };
|
|
356
|
+
}
|
|
357
|
+
function readNoydbBundleHeader(bytes) {
|
|
358
|
+
return parsePrefixAndHeader(bytes).header;
|
|
359
|
+
}
|
|
360
|
+
async function readNoydbBundle(bytes) {
|
|
361
|
+
const { header, bodyOffset, algo } = parsePrefixAndHeader(bytes);
|
|
362
|
+
const body = bytes.slice(bodyOffset);
|
|
363
|
+
if (body.length !== header.bodyBytes) {
|
|
364
|
+
throw new BundleIntegrityError(
|
|
365
|
+
`body length ${body.length} does not match header.bodyBytes ${header.bodyBytes}. The bundle was truncated or padded between write and read.`
|
|
366
|
+
);
|
|
367
|
+
}
|
|
368
|
+
const actualSha = await sha256Hex(body);
|
|
369
|
+
if (actualSha !== header.bodySha256) {
|
|
370
|
+
throw new BundleIntegrityError(
|
|
371
|
+
`body sha256 ${actualSha} does not match header.bodySha256 ${header.bodySha256}. The bundle bytes were modified between write and read \u2014 refuse to decompress.`
|
|
372
|
+
);
|
|
373
|
+
}
|
|
374
|
+
let dumpBytes;
|
|
375
|
+
if (algo === COMPRESSION_NONE) {
|
|
376
|
+
dumpBytes = body;
|
|
377
|
+
} else {
|
|
378
|
+
const streamFormat = algo === COMPRESSION_BROTLI ? "br" : "gzip";
|
|
379
|
+
try {
|
|
380
|
+
dumpBytes = await pumpThroughStream(body, new DecompressionStream(streamFormat));
|
|
381
|
+
} catch (err) {
|
|
382
|
+
throw new BundleIntegrityError(
|
|
383
|
+
`decompression failed: ${err.message}. The bundle passed the integrity hash but the body is not valid ${streamFormat} data \u2014 likely a producer bug.`
|
|
384
|
+
);
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
const dumpJson = new TextDecoder("utf-8", { fatal: true }).decode(dumpBytes);
|
|
388
|
+
return { header, dumpJson };
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
// src/bundle/ulid.ts
|
|
392
|
+
var CROCKFORD_ALPHABET = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
|
|
393
|
+
function encodeBase32(value, length) {
|
|
394
|
+
let out = "";
|
|
395
|
+
let v = value;
|
|
396
|
+
for (let i = 0; i < length; i++) {
|
|
397
|
+
out = CROCKFORD_ALPHABET[v % 32] + out;
|
|
398
|
+
v = Math.floor(v / 32);
|
|
399
|
+
}
|
|
400
|
+
return out;
|
|
401
|
+
}
|
|
402
|
+
function generateULID() {
|
|
403
|
+
const now = Date.now();
|
|
404
|
+
const timestampHigh = Math.floor(now / 16777216);
|
|
405
|
+
const timestampLow = now & 16777215;
|
|
406
|
+
const tsPart = encodeBase32(timestampHigh, 5) + encodeBase32(timestampLow, 5);
|
|
407
|
+
const randBytes = new Uint8Array(10);
|
|
408
|
+
crypto.getRandomValues(randBytes);
|
|
409
|
+
const rand1 = randBytes[0] * 2 ** 32 + (randBytes[1] << 24 >>> 0) + (randBytes[2] << 16) + (randBytes[3] << 8) + randBytes[4];
|
|
410
|
+
const rand2 = randBytes[5] * 2 ** 32 + (randBytes[6] << 24 >>> 0) + (randBytes[7] << 16) + (randBytes[8] << 8) + randBytes[9];
|
|
411
|
+
const randPart = encodeBase32(rand1, 8) + encodeBase32(rand2, 8);
|
|
412
|
+
return tsPart + randPart;
|
|
413
|
+
}
|
|
414
|
+
function isULID(value) {
|
|
415
|
+
return /^[0-9A-HJKMNP-TV-Z]{26}$/.test(value);
|
|
416
|
+
}
|
|
417
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
418
|
+
0 && (module.exports = {
|
|
419
|
+
COMPRESSION_BROTLI,
|
|
420
|
+
COMPRESSION_GZIP,
|
|
421
|
+
COMPRESSION_NONE,
|
|
422
|
+
FLAG_COMPRESSED,
|
|
423
|
+
FLAG_HAS_INTEGRITY_HASH,
|
|
424
|
+
NOYDB_BUNDLE_FORMAT_VERSION,
|
|
425
|
+
NOYDB_BUNDLE_MAGIC,
|
|
426
|
+
NOYDB_BUNDLE_PREFIX_BYTES,
|
|
427
|
+
encodeBundleHeader,
|
|
428
|
+
generateULID,
|
|
429
|
+
isULID,
|
|
430
|
+
readNoydbBundle,
|
|
431
|
+
readNoydbBundleHeader,
|
|
432
|
+
resetBrotliSupportCache,
|
|
433
|
+
validateBundleHeader,
|
|
434
|
+
writeNoydbBundle
|
|
435
|
+
});
|
|
436
|
+
//# sourceMappingURL=index.cjs.map
|