@tensorix/metahub 0.1.2

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.
Files changed (77) hide show
  1. package/README.md +162 -0
  2. package/dist/cli.js +20961 -0
  3. package/dist/cli.js.map +143 -0
  4. package/dist/core/blocks.d.ts +22 -0
  5. package/dist/core/blocks.d.ts.map +1 -0
  6. package/dist/core/cache.d.ts +10 -0
  7. package/dist/core/cache.d.ts.map +1 -0
  8. package/dist/core/context.d.ts +11 -0
  9. package/dist/core/context.d.ts.map +1 -0
  10. package/dist/core/crdt.d.ts +35 -0
  11. package/dist/core/crdt.d.ts.map +1 -0
  12. package/dist/core/csv.d.ts +14 -0
  13. package/dist/core/csv.d.ts.map +1 -0
  14. package/dist/core/databases.d.ts +19 -0
  15. package/dist/core/databases.d.ts.map +1 -0
  16. package/dist/core/db.d.ts +13 -0
  17. package/dist/core/db.d.ts.map +1 -0
  18. package/dist/core/documents.d.ts +50 -0
  19. package/dist/core/documents.d.ts.map +1 -0
  20. package/dist/core/fracdex.d.ts +5 -0
  21. package/dist/core/fracdex.d.ts.map +1 -0
  22. package/dist/core/hlc.d.ts +13 -0
  23. package/dist/core/hlc.d.ts.map +1 -0
  24. package/dist/core/ids.d.ts +17 -0
  25. package/dist/core/ids.d.ts.map +1 -0
  26. package/dist/core/index.d.ts +22 -0
  27. package/dist/core/index.d.ts.map +1 -0
  28. package/dist/core/indexing.d.ts +16 -0
  29. package/dist/core/indexing.d.ts.map +1 -0
  30. package/dist/core/node.d.ts +4 -0
  31. package/dist/core/node.d.ts.map +1 -0
  32. package/dist/core/paths.d.ts +4 -0
  33. package/dist/core/paths.d.ts.map +1 -0
  34. package/dist/core/properties.d.ts +35 -0
  35. package/dist/core/properties.d.ts.map +1 -0
  36. package/dist/core/records.d.ts +18 -0
  37. package/dist/core/records.d.ts.map +1 -0
  38. package/dist/core/resolve.d.ts +33 -0
  39. package/dist/core/resolve.d.ts.map +1 -0
  40. package/dist/core/schema.d.ts +3 -0
  41. package/dist/core/schema.d.ts.map +1 -0
  42. package/dist/core/search.d.ts +12 -0
  43. package/dist/core/search.d.ts.map +1 -0
  44. package/dist/core/sites.d.ts +45 -0
  45. package/dist/core/sites.d.ts.map +1 -0
  46. package/dist/core/snapshot.d.ts +58 -0
  47. package/dist/core/snapshot.d.ts.map +1 -0
  48. package/dist/core/sync/auth.d.ts +39 -0
  49. package/dist/core/sync/auth.d.ts.map +1 -0
  50. package/dist/core/sync/client.d.ts +8 -0
  51. package/dist/core/sync/client.d.ts.map +1 -0
  52. package/dist/core/sync/files.d.ts +17 -0
  53. package/dist/core/sync/files.d.ts.map +1 -0
  54. package/dist/core/sync/openapi.d.ts +14 -0
  55. package/dist/core/sync/openapi.d.ts.map +1 -0
  56. package/dist/core/sync/protocol.d.ts +49 -0
  57. package/dist/core/sync/protocol.d.ts.map +1 -0
  58. package/dist/core/sync/routes.d.ts +22 -0
  59. package/dist/core/sync/routes.d.ts.map +1 -0
  60. package/dist/core/sync/server.d.ts +21 -0
  61. package/dist/core/sync/server.d.ts.map +1 -0
  62. package/dist/core/sync/sites-routes.d.ts +3 -0
  63. package/dist/core/sync/sites-routes.d.ts.map +1 -0
  64. package/dist/core/sync/sites-serve.d.ts +3 -0
  65. package/dist/core/sync/sites-serve.d.ts.map +1 -0
  66. package/dist/core/sync/token.d.ts +23 -0
  67. package/dist/core/sync/token.d.ts.map +1 -0
  68. package/dist/core/sync/webui-routes.d.ts +3 -0
  69. package/dist/core/sync/webui-routes.d.ts.map +1 -0
  70. package/dist/core/sync/webui.d.ts +4 -0
  71. package/dist/core/sync/webui.d.ts.map +1 -0
  72. package/dist/index.d.ts +2 -0
  73. package/dist/index.d.ts.map +1 -0
  74. package/dist/index.js +17389 -0
  75. package/dist/index.js.map +114 -0
  76. package/dist/webui.js +34 -0
  77. package/package.json +41 -0
@@ -0,0 +1,22 @@
1
+ /** Split markdown into block texts (no leading/trailing blank lines, no empties). */
2
+ export declare function parseBlocks(md: string): string[];
3
+ /** Join block texts back into a markdown body. */
4
+ export declare function serializeBlocks(texts: readonly (string | null)[]): string;
5
+ export type ReconcileItem = {
6
+ keep: number;
7
+ } | {
8
+ insert: string;
9
+ };
10
+ export interface ReconcilePlan {
11
+ /** The new block sequence, each item either reusing an old block or inserting text. */
12
+ items: ReconcileItem[];
13
+ /** Old block indices that are no longer present. */
14
+ deleted: number[];
15
+ }
16
+ /**
17
+ * Align a new sequence of block texts against the old one. Unchanged blocks
18
+ * (exact text match, in order — the LCS) are kept by index so their identity and
19
+ * order survive; everything else in a gap is a delete (old) or insert (new).
20
+ */
21
+ export declare function reconcile(oldTexts: string[], newTexts: string[]): ReconcilePlan;
22
+ //# sourceMappingURL=blocks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blocks.d.ts","sourceRoot":"","sources":["../../src/core/blocks.ts"],"names":[],"mappings":"AAIA,qFAAqF;AACrF,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,EAAE,CA8ChD;AAED,kDAAkD;AAClD,wBAAgB,eAAe,CAAC,KAAK,EAAE,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,GAAG,MAAM,CAEzE;AAED,MAAM,MAAM,aAAa,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAClE,MAAM,WAAW,aAAa;IAC5B,uFAAuF;IACvF,KAAK,EAAE,aAAa,EAAE,CAAC;IACvB,oDAAoD;IACpD,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,aAAa,CAa/E"}
@@ -0,0 +1,10 @@
1
+ export interface BlobInfo {
2
+ hash: string;
3
+ path: string;
4
+ size: number;
5
+ }
6
+ export declare function blobPath(hash: string): string;
7
+ /** Store bytes content-addressed (sha256) under cache/. Returns its hash + path. */
8
+ export declare function putBlob(data: ArrayBuffer | Uint8Array | string): Promise<BlobInfo>;
9
+ export declare function getBlob(hash: string): Promise<Uint8Array | null>;
10
+ //# sourceMappingURL=cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../src/core/cache.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE7C;AAED,oFAAoF;AACpF,wBAAsB,OAAO,CAAC,IAAI,EAAE,WAAW,GAAG,UAAU,GAAG,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAaxF;AAED,wBAAsB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAItE"}
@@ -0,0 +1,11 @@
1
+ import type { Database } from "bun:sqlite";
2
+ import { type DatabaseRow } from "./databases.ts";
3
+ /**
4
+ * The current database, or null. Validated on read: if it points at a database
5
+ * that no longer exists (deleted, or gone after a snapshot restore), the stale
6
+ * pointer is cleared and null returned — no coupling to delete/restore paths.
7
+ */
8
+ export declare function getCurrentDatabase(db: Database): DatabaseRow | null;
9
+ export declare function setCurrentDatabase(db: Database, id: string): void;
10
+ export declare function clearCurrentDatabase(db: Database): void;
11
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/core/context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAe,KAAK,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAO/D;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,QAAQ,GAAG,WAAW,GAAG,IAAI,CAWnE;AAED,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI,CAIjE;AAED,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,QAAQ,GAAG,IAAI,CAEvD"}
@@ -0,0 +1,35 @@
1
+ import type { Database } from "bun:sqlite";
2
+ export interface Change {
3
+ hlc: string;
4
+ node_id: string;
5
+ dataset: string;
6
+ row_id: string;
7
+ col: string;
8
+ value: string | null;
9
+ }
10
+ /**
11
+ * Record a change in the oplog (idempotent) and, if it is the latest write for
12
+ * its register, materialize it. Order-independent: convergence holds regardless
13
+ * of the order changes are applied, because the winner is recomputed as the max
14
+ * HLC over the full oplog for that register.
15
+ */
16
+ export declare function applyChange(db: Database, c: Change): boolean;
17
+ /** Apply a local write: assign a fresh HLC, append to oplog, materialize. */
18
+ export declare function emit(db: Database, dataset: string, rowId: string, col: string, value: unknown): Change;
19
+ /** Apply multiple local field writes to the same row. */
20
+ export declare function emitFields(db: Database, dataset: string, rowId: string, fields: Record<string, unknown>): Change[];
21
+ /** Apply remote changes from a sync peer (advances clock, then merges). */
22
+ export declare function ingest(db: Database, changes: Change[]): number;
23
+ /** All oplog changes with HLC strictly greater than `since` (test/debug helper). */
24
+ export declare function changesSince(db: Database, since: string): Change[];
25
+ export interface ChangeBatch {
26
+ changes: Change[];
27
+ cursor: number;
28
+ }
29
+ /**
30
+ * Changes inserted after `seq` (a local rowid), in insertion order, plus the
31
+ * new high-water cursor. Used for replication: insertion order never skips a
32
+ * change even when clocks are skewed.
33
+ */
34
+ export declare function changesAfterSeq(db: Database, seq: number): ChangeBatch;
35
+ //# sourceMappingURL=crdt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crdt.d.ts","sourceRoot":"","sources":["../../src/core/crdt.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAO3C,MAAM,WAAW,MAAM;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AA0ID;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAc5D;AAED,6EAA6E;AAC7E,wBAAgB,IAAI,CAClB,EAAE,EAAE,QAAQ,EACZ,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,OAAO,GACb,MAAM,CAYR;AAED,yDAAyD;AACzD,wBAAgB,UAAU,CACxB,EAAE,EAAE,QAAQ,EACZ,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,MAAM,EAAE,CAMV;AAED,2EAA2E;AAC3E,wBAAgB,MAAM,CAAC,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM,CAW9D;AAED,oFAAoF;AACpF,wBAAgB,YAAY,CAAC,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAMlE;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,GAAG,WAAW,CAStE"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Minimal RFC-4180 CSV (no dependency). A cell is quoted only when it must be —
3
+ * it contains a comma, a double quote, or a newline — and embedded quotes are
4
+ * doubled. Parsing is the inverse and tolerates `\r\n`, a trailing newline, and
5
+ * quotes anywhere inside a quoted field.
6
+ */
7
+ /** Serialize a grid of strings to CSV text (rows joined with `\n`). */
8
+ export declare function toCsv(rows: string[][]): string;
9
+ /**
10
+ * Parse CSV text into a grid of strings. A single trailing newline is ignored;
11
+ * an empty input yields no rows.
12
+ */
13
+ export declare function parseCsv(text: string): string[][];
14
+ //# sourceMappingURL=csv.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"csv.d.ts","sourceRoot":"","sources":["../../src/core/csv.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAQH,uEAAuE;AACvE,wBAAgB,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,MAAM,CAE9C;AAED;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,EAAE,CA+CjD"}
@@ -0,0 +1,19 @@
1
+ import type { Database } from "bun:sqlite";
2
+ export interface DatabaseRow {
3
+ id: string;
4
+ name: string;
5
+ icon: string | null;
6
+ created_hlc: string;
7
+ }
8
+ export declare function createDatabase(db: Database, opts: {
9
+ name: string;
10
+ icon?: string;
11
+ }): DatabaseRow;
12
+ export declare function updateDatabase(db: Database, id: string, fields: {
13
+ name?: string;
14
+ icon?: string | null;
15
+ }): DatabaseRow;
16
+ export declare function getDatabase(db: Database, id: string): DatabaseRow | null;
17
+ export declare function listDatabases(db: Database): DatabaseRow[];
18
+ export declare function deleteDatabase(db: Database, id: string): boolean;
19
+ //# sourceMappingURL=databases.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"databases.d.ts","sourceRoot":"","sources":["../../src/core/databases.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAI3C,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,cAAc,CAC5B,EAAE,EAAE,QAAQ,EACZ,IAAI,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GACpC,WAAW,CAMb;AAED,wBAAgB,cAAc,CAC5B,EAAE,EAAE,QAAQ,EACZ,EAAE,EAAE,MAAM,EACV,MAAM,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAC9C,WAAW,CAKb;AAED,wBAAgB,WAAW,CAAC,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAMxE;AAED,wBAAgB,aAAa,CAAC,EAAE,EAAE,QAAQ,GAAG,WAAW,EAAE,CAMzD;AAED,wBAAgB,cAAc,CAAC,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAOhE"}
@@ -0,0 +1,13 @@
1
+ import { Database } from "bun:sqlite";
2
+ export declare function ensureDirs(): void;
3
+ export declare function runSchema(db: Database): void;
4
+ export declare function ftsAvailable(db: Database): boolean;
5
+ /**
6
+ * Migrate legacy EAV records (record_values: one row per cell) to the JSON
7
+ * layout (records.data: one row per record). Idempotent — keyed off schema
8
+ * shape, no version flag. A no-op for fresh databases.
9
+ */
10
+ export declare function migrateRecords(db: Database): void;
11
+ /** Open (and migrate) the on-disk metahub database for the resolved home. */
12
+ export declare function openMetahub(): Database;
13
+ //# sourceMappingURL=db.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../../src/core/db.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAMtC,wBAAgB,UAAU,IAAI,IAAI,CAGjC;AAED,wBAAgB,SAAS,CAAC,EAAE,EAAE,QAAQ,GAAG,IAAI,CAO5C;AAED,wBAAgB,YAAY,CAAC,EAAE,EAAE,QAAQ,GAAG,OAAO,CAKlD;AAeD;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,EAAE,EAAE,QAAQ,GAAG,IAAI,CAuBjD;AAED,6EAA6E;AAC7E,wBAAgB,WAAW,IAAI,QAAQ,CAOtC"}
@@ -0,0 +1,50 @@
1
+ import type { Database } from "bun:sqlite";
2
+ export interface DocumentRow {
3
+ id: string;
4
+ title: string;
5
+ body: string | null;
6
+ database_id: string | null;
7
+ parent_id: string | null;
8
+ created_hlc: string;
9
+ }
10
+ export type DocumentSummary = Omit<DocumentRow, "body">;
11
+ /** Max HLC over a document's own register and all its blocks — a read/edit token. */
12
+ export declare function documentVersion(db: Database, id: string): string;
13
+ export declare function createDocument(db: Database, opts: {
14
+ title: string;
15
+ body?: string;
16
+ database_id?: string;
17
+ parent_id?: string;
18
+ }): DocumentRow;
19
+ export declare function getDocument(db: Database, id: string): DocumentRow | null;
20
+ export declare function listDocuments(db: Database, opts?: {
21
+ database_id?: string;
22
+ }): DocumentSummary[];
23
+ export declare function updateDocument(db: Database, id: string, fields: {
24
+ title?: string;
25
+ body?: string;
26
+ database_id?: string;
27
+ parent_id?: string | null;
28
+ }): DocumentRow;
29
+ export interface EditDocResult {
30
+ id: string;
31
+ changed: boolean;
32
+ replaced: number;
33
+ version: string;
34
+ }
35
+ /**
36
+ * Anchored find/replace, like the Edit tool. `old` must occur exactly once
37
+ * (or pass `replaceAll`); supplying it is the read-before-edit guarantee — you
38
+ * cannot author it without current content, and drift surfaces as "not found".
39
+ * `ifMatch` is an optional staleness backstop (a version from documentVersion).
40
+ */
41
+ export declare function editDocument(db: Database, id: string, opts: {
42
+ old: string;
43
+ new: string;
44
+ replaceAll?: boolean;
45
+ ifMatch?: string;
46
+ }): EditDocResult;
47
+ export declare function appendDocument(db: Database, id: string, body: string): EditDocResult;
48
+ export declare function prependDocument(db: Database, id: string, body: string): EditDocResult;
49
+ export declare function deleteDocument(db: Database, id: string): boolean;
50
+ //# sourceMappingURL=documents.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"documents.d.ts","sourceRoot":"","sources":["../../src/core/documents.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAM3C,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,MAAM,eAAe,GAAG,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;AAmFxD,qFAAqF;AACrF,wBAAgB,eAAe,CAAC,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAShE;AAID,wBAAgB,cAAc,CAC5B,EAAE,EAAE,QAAQ,EACZ,IAAI,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAC/E,WAAW,CAWb;AAED,wBAAgB,WAAW,CAAC,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAMxE;AAED,wBAAgB,aAAa,CAC3B,EAAE,EAAE,QAAQ,EACZ,IAAI,GAAE;IAAE,WAAW,CAAC,EAAE,MAAM,CAAA;CAAO,GAClC,eAAe,EAAE,CAYnB;AAED,wBAAgB,cAAc,CAC5B,EAAE,EAAE,QAAQ,EACZ,EAAE,EAAE,MAAM,EACV,MAAM,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GACzF,WAAW,CAoBb;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAC1B,EAAE,EAAE,QAAQ,EACZ,EAAE,EAAE,MAAM,EACV,IAAI,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GACzE,aAAa,CAmCf;AAED,wBAAgB,cAAc,CAAC,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,aAAa,CAUpF;AAED,wBAAgB,eAAe,CAAC,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,aAAa,CAUrF;AAED,wBAAgB,cAAc,CAAC,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAIhE"}
@@ -0,0 +1,5 @@
1
+ /** A key strictly between `a` and `b` (lexicographically). null = open boundary. */
2
+ export declare function keyBetween(a: string | null, b: string | null): string;
3
+ /** `n` distinct keys in ascending order, all strictly between `a` and `b`. */
4
+ export declare function keysBetween(a: string | null, b: string | null, n: number): string[];
5
+ //# sourceMappingURL=fracdex.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fracdex.d.ts","sourceRoot":"","sources":["../../src/core/fracdex.ts"],"names":[],"mappings":"AAsCA,oFAAoF;AACpF,wBAAgB,UAAU,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAErE;AAED,8EAA8E;AAC9E,wBAAgB,WAAW,CACzB,CAAC,EAAE,MAAM,GAAG,IAAI,EAChB,CAAC,EAAE,MAAM,GAAG,IAAI,EAChB,CAAC,EAAE,MAAM,GACR,MAAM,EAAE,CA2BV"}
@@ -0,0 +1,13 @@
1
+ import type { Database } from "bun:sqlite";
2
+ export interface Hlc {
3
+ millis: number;
4
+ counter: number;
5
+ node: string;
6
+ }
7
+ export declare function formatHlc(h: Hlc): string;
8
+ export declare function parseHlc(s: string): Hlc;
9
+ /** Issue a new timestamp for a local event, advancing the persisted clock. */
10
+ export declare function nextHlc(db: Database, node: string, now?: number): string;
11
+ /** Advance the local clock to account for an observed remote timestamp. */
12
+ export declare function observeHlc(db: Database, node: string, remote: string, now?: number): void;
13
+ //# sourceMappingURL=hlc.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hlc.d.ts","sourceRoot":"","sources":["../../src/core/hlc.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAK3C,MAAM,WAAW,GAAG;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,wBAAgB,SAAS,CAAC,CAAC,EAAE,GAAG,GAAG,MAAM,CAIxC;AAED,wBAAgB,QAAQ,CAAC,CAAC,EAAE,MAAM,GAAG,GAAG,CAQvC;AAeD,8EAA8E;AAC9E,wBAAgB,OAAO,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,SAAa,GAAG,MAAM,CAO5E;AAED,2EAA2E;AAC3E,wBAAgB,UAAU,CACxB,EAAE,EAAE,QAAQ,EACZ,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,GAAG,SAAa,GACf,IAAI,CAWN"}
@@ -0,0 +1,17 @@
1
+ /** Collision-resistant lowercase token (base36). */
2
+ export declare function randomSuffix(len?: number): string;
3
+ /** ASCII-only, url-safe slug from an arbitrary name. Empty -> fallback. */
4
+ export declare function slugify(name: string, fallback?: string): string;
5
+ /** id = slug(name) + "-" + random. Readable yet safe for offline multi-node creation. */
6
+ export declare function makeId(name: string, fallback?: string): string;
7
+ /** Entity kinds whose ids carry a type prefix. */
8
+ export type Kind = "db" | "prop" | "rec" | "doc" | "blk" | "site" | "sf";
9
+ /**
10
+ * Typed id = "<kind>_<slug>-<rand>". `slugify` emits only [a-z0-9-] and
11
+ * `randomSuffix` only base36, so the FIRST "_" is unambiguously the type
12
+ * separator — `idKind` recovers the kind, and legacy ids (no "_") read as null.
13
+ */
14
+ export declare function newId(kind: Kind, name: string, fallback?: string): string;
15
+ /** The kind encoded in a typed id, or null for legacy (prefix-less) ids. */
16
+ export declare function idKind(id: string): Kind | null;
17
+ //# sourceMappingURL=ids.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ids.d.ts","sourceRoot":"","sources":["../../src/core/ids.ts"],"names":[],"mappings":"AAEA,oDAAoD;AACpD,wBAAgB,YAAY,CAAC,GAAG,SAAI,GAAG,MAAM,CAK5C;AAED,2EAA2E;AAC3E,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,SAAS,GAAG,MAAM,CAU/D;AAED,yFAAyF;AACzF,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,SAAS,GAAG,MAAM,CAE9D;AAED,kDAAkD;AAClD,MAAM,MAAM,IAAI,GAAG,IAAI,GAAG,MAAM,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,MAAM,GAAG,IAAI,CAAC;AAYzE;;;;GAIG;AACH,wBAAgB,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,GAAE,MAAa,GAAG,MAAM,CAE/E;AAED,4EAA4E;AAC5E,wBAAgB,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAK9C"}
@@ -0,0 +1,22 @@
1
+ export * from "./paths.ts";
2
+ export * from "./db.ts";
3
+ export * from "./ids.ts";
4
+ export * from "./resolve.ts";
5
+ export * from "./hlc.ts";
6
+ export * from "./crdt.ts";
7
+ export * from "./blocks.ts";
8
+ export * from "./fracdex.ts";
9
+ export * from "./node.ts";
10
+ export * from "./databases.ts";
11
+ export * from "./context.ts";
12
+ export * from "./properties.ts";
13
+ export * from "./indexing.ts";
14
+ export * from "./records.ts";
15
+ export * from "./documents.ts";
16
+ export * from "./search.ts";
17
+ export * from "./cache.ts";
18
+ export * from "./sites.ts";
19
+ export * from "./sync/protocol.ts";
20
+ export * from "./sync/client.ts";
21
+ export * from "./sync/server.ts";
22
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,SAAS,CAAC;AACxB,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC;AAC1B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC"}
@@ -0,0 +1,16 @@
1
+ import type { Database } from "bun:sqlite";
2
+ import type { PropertyRow } from "./properties.ts";
3
+ export declare function hasIndex(db: Database, databaseId: string, propId: string): boolean;
4
+ /**
5
+ * Create an expression index on `data ->> '<propId>'` (with created_hlc as the
6
+ * sort tail), partial on this database. Idempotent. The expression matches
7
+ * exactly what listRecords emits, so the optimizer uses it.
8
+ */
9
+ export declare function ensurePropIndex(db: Database, databaseId: string, propId: string): void;
10
+ /**
11
+ * Ensure an index for a field that a query filters/sorts on — but only when it
12
+ * will pay off. relation fields are almost always query keys (cheap, index
13
+ * eagerly); other fields wait until the collection crosses the row threshold.
14
+ */
15
+ export declare function maybeAutoIndex(db: Database, databaseId: string, prop: PropertyRow): void;
16
+ //# sourceMappingURL=indexing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"indexing.d.ts","sourceRoot":"","sources":["../../src/core/indexing.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAsBnD,wBAAgB,QAAQ,CAAC,EAAE,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAKlF;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,EAAE,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAMtF;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,EAAE,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,GAAG,IAAI,CAWxF"}
@@ -0,0 +1,4 @@
1
+ import type { Database } from "bun:sqlite";
2
+ /** Stable per-machine node id, persisted in the meta table. */
3
+ export declare function getNodeId(db: Database): string;
4
+ //# sourceMappingURL=node.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../src/core/node.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAG3C,+DAA+D;AAC/D,wBAAgB,SAAS,CAAC,EAAE,EAAE,QAAQ,GAAG,MAAM,CAQ9C"}
@@ -0,0 +1,4 @@
1
+ export declare function metahubHome(): string;
2
+ export declare function dbPath(): string;
3
+ export declare function cacheDir(): string;
4
+ //# sourceMappingURL=paths.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/core/paths.ts"],"names":[],"mappings":"AAGA,wBAAgB,WAAW,IAAI,MAAM,CAEpC;AAED,wBAAgB,MAAM,IAAI,MAAM,CAE/B;AAED,wBAAgB,QAAQ,IAAI,MAAM,CAEjC"}
@@ -0,0 +1,35 @@
1
+ import type { Database } from "bun:sqlite";
2
+ export type PropType = "text" | "number" | "checkbox" | "select" | "multi_select" | "date" | "relation" | "url";
3
+ export declare const PROP_TYPES: ReadonlySet<string>;
4
+ export interface PropertyConfig {
5
+ options?: string[];
6
+ database?: string;
7
+ indexed?: boolean;
8
+ width?: number;
9
+ }
10
+ export interface PropertyRow {
11
+ id: string;
12
+ database_id: string;
13
+ name: string;
14
+ type: PropType;
15
+ config: PropertyConfig | null;
16
+ position: number;
17
+ }
18
+ export declare function addProperty(db: Database, databaseId: string, opts: {
19
+ name: string;
20
+ type: PropType;
21
+ config?: PropertyConfig;
22
+ position?: number;
23
+ indexed?: boolean;
24
+ }): PropertyRow;
25
+ export declare function getProperty(db: Database, id: string): PropertyRow | null;
26
+ export declare function listProperties(db: Database, databaseId: string): PropertyRow[];
27
+ export declare function updateProperty(db: Database, id: string, fields: {
28
+ name?: string;
29
+ type?: PropType;
30
+ config?: PropertyConfig;
31
+ position?: number;
32
+ }): PropertyRow;
33
+ export declare function setPropertyWidth(db: Database, id: string, width: number): PropertyRow;
34
+ export declare function removeProperty(db: Database, id: string): boolean;
35
+ //# sourceMappingURL=properties.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"properties.d.ts","sourceRoot":"","sources":["../../src/core/properties.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAM3C,MAAM,MAAM,QAAQ,GAChB,MAAM,GACN,QAAQ,GACR,UAAU,GACV,QAAQ,GACR,cAAc,GACd,MAAM,GACN,UAAU,GACV,KAAK,CAAC;AAEV,eAAO,MAAM,UAAU,EAAE,WAAW,CAAC,MAAM,CASzC,CAAC;AAEH,MAAM,WAAW,cAAc;IAC7B,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,QAAQ,CAAC;IACf,MAAM,EAAE,cAAc,GAAG,IAAI,CAAC;IAC9B,QAAQ,EAAE,MAAM,CAAC;CAClB;AAuBD,wBAAgB,WAAW,CACzB,EAAE,EAAE,QAAQ,EACZ,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE;IACJ,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,QAAQ,CAAC;IACf,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAIlB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,GACA,WAAW,CAsBb;AAED,wBAAgB,WAAW,CAAC,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAQxE;AAED,wBAAgB,cAAc,CAAC,EAAE,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,GAAG,WAAW,EAAE,CAU9E;AAED,wBAAgB,cAAc,CAC5B,EAAE,EAAE,QAAQ,EACZ,EAAE,EAAE,MAAM,EACV,MAAM,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,QAAQ,CAAC;IAAC,MAAM,CAAC,EAAE,cAAc,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GACrF,WAAW,CA8Bb;AAKD,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,WAAW,CAMrF;AAED,wBAAgB,cAAc,CAAC,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAIhE"}
@@ -0,0 +1,18 @@
1
+ import type { Database } from "bun:sqlite";
2
+ export interface RecordRow {
3
+ id: string;
4
+ database_id: string;
5
+ values: Record<string, unknown>;
6
+ }
7
+ export declare function backfillRecordOrderKeys(db: Database, databaseId?: string): void;
8
+ export declare function createRecord(db: Database, databaseId: string, data: Record<string, unknown>): RecordRow;
9
+ export declare function getRecord(db: Database, id: string): RecordRow | null;
10
+ export declare function listRecords(db: Database, databaseId: string, opts?: {
11
+ filter?: Record<string, unknown>;
12
+ sort?: string;
13
+ limit?: number;
14
+ }): RecordRow[];
15
+ export declare function moveRecord(db: Database, id: string, targetId: string, where: "before" | "after"): RecordRow;
16
+ export declare function updateRecord(db: Database, id: string, data: Record<string, unknown>): RecordRow;
17
+ export declare function deleteRecord(db: Database, id: string): boolean;
18
+ //# sourceMappingURL=records.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"records.d.ts","sourceRoot":"","sources":["../../src/core/records.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAqB3C,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC;AAiKD,wBAAgB,uBAAuB,CAAC,EAAE,EAAE,QAAQ,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAyB/E;AAED,wBAAgB,YAAY,CAC1B,EAAE,EAAE,QAAQ,EACZ,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,SAAS,CAcX;AAED,wBAAgB,SAAS,CAAC,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAMpE;AAOD,wBAAgB,WAAW,CACzB,EAAE,EAAE,QAAQ,EACZ,UAAU,EAAE,MAAM,EAClB,IAAI,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAO,GAC7E,SAAS,EAAE,CA0Eb;AAED,wBAAgB,UAAU,CACxB,EAAE,EAAE,QAAQ,EACZ,EAAE,EAAE,MAAM,EACV,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,QAAQ,GAAG,OAAO,GACxB,SAAS,CAqCX;AAED,wBAAgB,YAAY,CAC1B,EAAE,EAAE,QAAQ,EACZ,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,SAAS,CASX;AAED,wBAAgB,YAAY,CAAC,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAO9D"}
@@ -0,0 +1,33 @@
1
+ import type { Database } from "bun:sqlite";
2
+ /** Kinds reachable through the public reference resolver. `blk` is internal. */
3
+ export type PublicKind = "db" | "prop" | "rec" | "doc";
4
+ export interface Candidate {
5
+ kind: PublicKind;
6
+ id: string;
7
+ label: string;
8
+ }
9
+ /**
10
+ * Every entity matching `ref`. Kind scope: an explicit `opts.kind` (the command
11
+ * knows what it wants) wins; otherwise a typed prefix on `ref` dispatches; else
12
+ * all public kinds are searched (the generic `mh get`). `databaseId` narrows
13
+ * rec/doc/prop to one collection.
14
+ */
15
+ export declare function resolveCandidates(db: Database, ref: string, opts?: {
16
+ kind?: PublicKind;
17
+ databaseId?: string;
18
+ }): Candidate[];
19
+ /**
20
+ * Resolve `ref` to one entity. An exact full-id match always wins (the full id
21
+ * keeps working). Otherwise a single candidate is returned; zero throws
22
+ * "no such …"; multiple throws a git-style ambiguity list.
23
+ */
24
+ export declare function resolveEntity(db: Database, ref: string, opts?: {
25
+ kind?: PublicKind;
26
+ databaseId?: string;
27
+ }): Candidate;
28
+ /** Resolve `ref` to one concrete row id. See {@link resolveEntity}. */
29
+ export declare function resolveRef(db: Database, ref: string, opts?: {
30
+ kind?: PublicKind;
31
+ databaseId?: string;
32
+ }): string;
33
+ //# sourceMappingURL=resolve.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../src/core/resolve.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAG3C,gFAAgF;AAChF,MAAM,MAAM,UAAU,GAAG,IAAI,GAAG,MAAM,GAAG,KAAK,GAAG,KAAK,CAAC;AAEvD,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,UAAU,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;CACf;AAiFD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,EAAE,EAAE,QAAQ,EACZ,GAAG,EAAE,MAAM,EACX,IAAI,GAAE;IAAE,IAAI,CAAC,EAAE,UAAU,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAO,GACpD,SAAS,EAAE,CAiBb;AAQD;;;;GAIG;AACH,wBAAgB,aAAa,CAC3B,EAAE,EAAE,QAAQ,EACZ,GAAG,EAAE,MAAM,EACX,IAAI,GAAE;IAAE,IAAI,CAAC,EAAE,UAAU,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAO,GACpD,SAAS,CAcX;AAED,uEAAuE;AACvE,wBAAgB,UAAU,CACxB,EAAE,EAAE,QAAQ,EACZ,GAAG,EAAE,MAAM,EACX,IAAI,GAAE;IAAE,IAAI,CAAC,EAAE,UAAU,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAO,GACpD,MAAM,CAER"}
@@ -0,0 +1,3 @@
1
+ export declare const CORE_SCHEMA = "\nCREATE TABLE IF NOT EXISTS meta (\n key TEXT PRIMARY KEY,\n value TEXT\n);\n\n-- CRDT oplog: one row per field assignment. Source of truth for sync.\nCREATE TABLE IF NOT EXISTS crdt_changes (\n hlc TEXT NOT NULL,\n node_id TEXT NOT NULL,\n dataset TEXT NOT NULL,\n row_id TEXT NOT NULL,\n col TEXT NOT NULL,\n value TEXT,\n PRIMARY KEY (dataset, row_id, col, hlc)\n);\nCREATE INDEX IF NOT EXISTS idx_changes_hlc ON crdt_changes(hlc);\n\n-- Per-peer replication cursors (SQLite rowids: monotonic in insertion order,\n-- so no change is ever skipped regardless of HLC/clock skew).\nCREATE TABLE IF NOT EXISTS peers (\n url TEXT PRIMARY KEY,\n pull_cursor INTEGER NOT NULL DEFAULT 0,\n push_cursor INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE IF NOT EXISTS databases (\n id TEXT PRIMARY KEY,\n name TEXT,\n icon TEXT,\n created_hlc TEXT,\n __deleted INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE IF NOT EXISTS properties (\n id TEXT PRIMARY KEY,\n database_id TEXT,\n name TEXT,\n type TEXT,\n config TEXT,\n position REAL,\n __deleted INTEGER NOT NULL DEFAULT 0\n);\nCREATE INDEX IF NOT EXISTS idx_properties_db ON properties(database_id);\n\n-- One row per record. Field cells live in the data JSON object, keyed by\n-- property id (rename-safe). Each (record,property) is still an independent\n-- CRDT register in the oplog; materialize() folds the winner into data via\n-- json_set/json_remove. Hot fields get expression indexes on data->>'propid'\n-- (see indexing.ts) so filter/sort/limit push down to SQL.\nCREATE TABLE IF NOT EXISTS records (\n id TEXT PRIMARY KEY,\n database_id TEXT,\n created_hlc TEXT,\n order_key TEXT,\n data TEXT NOT NULL DEFAULT '{}',\n __deleted INTEGER NOT NULL DEFAULT 0\n);\nCREATE INDEX IF NOT EXISTS idx_records_db_hlc ON records(database_id, created_hlc);\n\nCREATE TABLE IF NOT EXISTS documents (\n id TEXT PRIMARY KEY,\n title TEXT,\n body TEXT, -- materialized cache: serialized from doc_blocks\n database_id TEXT,\n parent_id TEXT,\n created_hlc TEXT,\n __deleted INTEGER NOT NULL DEFAULT 0\n);\n\n-- Document body as an ordered list of blocks; each (block,field) is an\n-- independent CRDT register so concurrent edits to different blocks merge.\n-- order_key is a fractional index (ties broken by id) giving display order.\nCREATE TABLE IF NOT EXISTS doc_blocks (\n id TEXT PRIMARY KEY,\n doc_id TEXT,\n text TEXT,\n order_key TEXT,\n __deleted INTEGER NOT NULL DEFAULT 0\n);\nCREATE INDEX IF NOT EXISTS idx_doc_blocks_doc ON doc_blocks(doc_id);\n\n-- A named static site (Supabase-Storage-style bucket). Served at /sites/<name>/.\nCREATE TABLE IF NOT EXISTS sites (\n id TEXT PRIMARY KEY,\n name TEXT, -- URL slug; resolved by getSiteByName\n title TEXT,\n created_hlc TEXT,\n __deleted INTEGER NOT NULL DEFAULT 0\n);\n\n-- One row per file in a site. content holds inline utf8/base64 text, or a blob\n-- hash (see cache.ts) when encoding = 'blob'. (site_id, path) maps to a stable\n-- id so re-uploads merge as a CRDT register instead of duplicating.\nCREATE TABLE IF NOT EXISTS site_files (\n id TEXT PRIMARY KEY,\n site_id TEXT,\n path TEXT,\n content_type TEXT,\n encoding TEXT, -- 'utf8' | 'base64' | 'blob'\n content TEXT,\n created_hlc TEXT,\n __deleted INTEGER NOT NULL DEFAULT 0\n);\nCREATE INDEX IF NOT EXISTS idx_site_files_site ON site_files(site_id);\n";
2
+ export declare const FTS_SCHEMA = "\nCREATE VIRTUAL TABLE IF NOT EXISTS search_fts USING fts5(\n kind UNINDEXED,\n id UNINDEXED,\n database_id UNINDEXED,\n title,\n body\n);\n";
3
+ //# sourceMappingURL=schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/core/schema.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,WAAW,ygHAyGvB,CAAC;AAGF,eAAO,MAAM,UAAU,sJAQtB,CAAC"}
@@ -0,0 +1,12 @@
1
+ import type { Database } from "bun:sqlite";
2
+ export interface SearchHit {
3
+ type: "document" | "record";
4
+ id: string;
5
+ database_id: string | null;
6
+ title?: string;
7
+ snippet: string;
8
+ }
9
+ export declare function search(db: Database, query: string, opts?: {
10
+ limit?: number;
11
+ }): SearchHit[];
12
+ //# sourceMappingURL=search.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../src/core/search.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAG3C,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,UAAU,GAAG,QAAQ,CAAC;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB;AA2HD,wBAAgB,MAAM,CACpB,EAAE,EAAE,QAAQ,EACZ,KAAK,EAAE,MAAM,EACb,IAAI,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAO,GAC5B,SAAS,EAAE,CAWb"}
@@ -0,0 +1,45 @@
1
+ import type { Database } from "bun:sqlite";
2
+ export interface SiteRow {
3
+ id: string;
4
+ name: string;
5
+ title: string | null;
6
+ created_hlc: string;
7
+ }
8
+ export type FileEncoding = "utf8" | "base64" | "blob";
9
+ export interface SiteFileRow {
10
+ id: string;
11
+ site_id: string;
12
+ path: string;
13
+ content_type: string;
14
+ encoding: FileEncoding;
15
+ /** Inline text/base64, or a blob hash when encoding === "blob". */
16
+ content: string | null;
17
+ }
18
+ /** Manifest entry — file metadata without the (potentially large) content. */
19
+ export type SiteFileSummary = Omit<SiteFileRow, "content">;
20
+ /** Guess a content type from a file path's extension; default octet-stream. */
21
+ export declare function inferContentType(path: string): string;
22
+ export declare function createSite(db: Database, opts: {
23
+ name: string;
24
+ title?: string;
25
+ }): SiteRow;
26
+ export declare function getSite(db: Database, id: string): SiteRow | null;
27
+ /** Most recently created live site with this name (URL routing). */
28
+ export declare function getSiteByName(db: Database, name: string): SiteRow | null;
29
+ export declare function listSites(db: Database): SiteRow[];
30
+ /** Resolve a site ref (`site_…` id or name) to its row, or throw. */
31
+ export declare function resolveSite(db: Database, ref: string): SiteRow;
32
+ export declare function deleteSite(db: Database, id: string): boolean;
33
+ /** Upload or replace one file. Picks utf8 / base64 / blob storage automatically. */
34
+ export declare function putFile(db: Database, siteId: string, path: string, opts: {
35
+ data: string | Uint8Array | ArrayBuffer;
36
+ contentType?: string;
37
+ }): Promise<SiteFileRow>;
38
+ export declare function listFiles(db: Database, siteId: string): SiteFileSummary[];
39
+ export declare function deleteFile(db: Database, siteId: string, path: string): boolean;
40
+ /** Resolve a file to served bytes + content type. "" / trailing "/" → index.html. */
41
+ export declare function getFileForServe(db: Database, siteId: string, path: string): Promise<{
42
+ contentType: string;
43
+ bytes: Uint8Array;
44
+ } | null>;
45
+ //# sourceMappingURL=sites.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sites.d.ts","sourceRoot":"","sources":["../../src/core/sites.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAW3C,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,QAAQ,GAAG,MAAM,CAAC;AAEtD,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,YAAY,CAAC;IACvB,mEAAmE;IACnE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAED,8EAA8E;AAC9E,MAAM,MAAM,eAAe,GAAG,IAAI,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;AAkC3D,+EAA+E;AAC/E,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAGrD;AAuBD,wBAAgB,UAAU,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAOxF;AAED,wBAAgB,OAAO,CAAC,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI,CAIhE;AAED,oEAAoE;AACpE,wBAAgB,aAAa,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI,CAMxE;AAED,wBAAgB,SAAS,CAAC,EAAE,EAAE,QAAQ,GAAG,OAAO,EAAE,CAIjD;AAED,qEAAqE;AACrE,wBAAgB,WAAW,CAAC,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAK9D;AAED,wBAAgB,UAAU,CAAC,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAQ5D;AAYD,oFAAoF;AACpF,wBAAsB,OAAO,CAC3B,EAAE,EAAE,QAAQ,EACZ,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE;IAAE,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,WAAW,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,GACtE,OAAO,CAAC,WAAW,CAAC,CAkCtB;AAED,wBAAgB,SAAS,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAG,eAAe,EAAE,CAMzE;AAED,wBAAgB,UAAU,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAS9E;AAED,qFAAqF;AACrF,wBAAsB,eAAe,CACnC,EAAE,EAAE,QAAQ,EACZ,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,GACX,OAAO,CAAC;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,UAAU,CAAA;CAAE,GAAG,IAAI,CAAC,CAiB5D"}
@@ -0,0 +1,58 @@
1
+ import type { Database } from "bun:sqlite";
2
+ import { type Change } from "./crdt.ts";
3
+ export declare const SNAPSHOT_FORMAT = "metahub-snapshot";
4
+ export declare const SNAPSHOT_VERSION = 1;
5
+ export interface PeerRow {
6
+ url: string;
7
+ pull_cursor: number;
8
+ push_cursor: number;
9
+ }
10
+ export interface SnapshotPackage {
11
+ format: typeof SNAPSHOT_FORMAT;
12
+ version: number;
13
+ createdAt: string;
14
+ source: {
15
+ node_id: string | null;
16
+ hlc: string | null;
17
+ };
18
+ counts: {
19
+ changes: number;
20
+ blobs: number;
21
+ };
22
+ meta: {
23
+ node_id: string | null;
24
+ hlc: string | null;
25
+ };
26
+ peers: PeerRow[];
27
+ changes: Change[];
28
+ blobs: Record<string, string>;
29
+ }
30
+ /** Capture the whole hub (oplog + identity + peers + blobs) into a portable package. */
31
+ export declare function createSnapshot(db: Database): Promise<SnapshotPackage>;
32
+ export interface WriteResult {
33
+ counts: SnapshotPackage["counts"];
34
+ bytes: number;
35
+ }
36
+ /** Serialize a package to a gzip-compressed JSON file. */
37
+ export declare function writeSnapshot(pkg: SnapshotPackage, path: string): Promise<WriteResult>;
38
+ /** Read and validate a package file written by writeSnapshot. */
39
+ export declare function readSnapshot(path: string): Promise<SnapshotPackage>;
40
+ export interface RestoreResult {
41
+ mode: "merge" | "reset";
42
+ applied: number;
43
+ blobs: number;
44
+ safetyPath?: string;
45
+ }
46
+ /**
47
+ * Apply a package to the local hub.
48
+ * - merge (default): replay the package's oplog via ingest(); idempotent,
49
+ * last-writer-wins by HLC. Local identity/peers untouched.
50
+ * - reset: wipe and rebuild to match the package exactly. Destructive, so it
51
+ * first saves a safety snapshot of current state. Orphan blobs from the old
52
+ * state are left in cache/ (content-addressed, harmless).
53
+ */
54
+ export declare function restoreSnapshot(db: Database, pkg: SnapshotPackage, opts?: {
55
+ reset?: boolean;
56
+ force?: boolean;
57
+ }): Promise<RestoreResult>;
58
+ //# sourceMappingURL=snapshot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshot.d.ts","sourceRoot":"","sources":["../../src/core/snapshot.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAG3C,OAAO,EAA2B,KAAK,MAAM,EAAE,MAAM,WAAW,CAAC;AAMjE,eAAO,MAAM,eAAe,qBAAqB,CAAC;AAClD,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAElC,MAAM,WAAW,OAAO;IACtB,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,OAAO,eAAe,CAAC;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE;QAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;IACvD,MAAM,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAC3C,IAAI,EAAE;QAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;IACrD,KAAK,EAAE,OAAO,EAAE,CAAC;IACjB,OAAO,EAAE,MAAM,EAAE,CAAC;IAElB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC/B;AAoBD,wFAAwF;AACxF,wBAAsB,cAAc,CAAC,EAAE,EAAE,QAAQ,GAAG,OAAO,CAAC,eAAe,CAAC,CAoB3E;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,eAAe,CAAC,QAAQ,CAAC,CAAC;IAClC,KAAK,EAAE,MAAM,CAAC;CACf;AAED,0DAA0D;AAC1D,wBAAsB,aAAa,CACjC,GAAG,EAAE,eAAe,EACpB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,WAAW,CAAC,CAItB;AAED,iEAAiE;AACjE,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAiBzE;AAoCD,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;GAOG;AACH,wBAAsB,eAAe,CACnC,EAAE,EAAE,QAAQ,EACZ,GAAG,EAAE,eAAe,EACpB,IAAI,GAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAO,GAC9C,OAAO,CAAC,aAAa,CAAC,CAiDxB"}