@opendatalabs/personal-server-ts-server 0.2.0 → 1.1.0

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 (177) hide show
  1. package/dist/api-auth.d.ts +16 -0
  2. package/dist/api-auth.d.ts.map +1 -0
  3. package/dist/api-auth.js +97 -0
  4. package/dist/api-auth.js.map +1 -0
  5. package/dist/api.d.ts +4 -0
  6. package/dist/api.d.ts.map +1 -1
  7. package/dist/api.js +3 -0
  8. package/dist/api.js.map +1 -1
  9. package/dist/app.d.ts +46 -1
  10. package/dist/app.d.ts.map +1 -1
  11. package/dist/app.js +102 -30
  12. package/dist/app.js.map +1 -1
  13. package/dist/bootstrap.d.ts +11 -3
  14. package/dist/bootstrap.d.ts.map +1 -1
  15. package/dist/bootstrap.js +266 -33
  16. package/dist/bootstrap.js.map +1 -1
  17. package/dist/client.d.ts +17 -0
  18. package/dist/client.d.ts.map +1 -0
  19. package/dist/client.js +368 -0
  20. package/dist/client.js.map +1 -0
  21. package/dist/config/defaults.d.ts +12 -0
  22. package/dist/config/defaults.d.ts.map +1 -0
  23. package/dist/config/defaults.js +14 -0
  24. package/dist/config/defaults.js.map +1 -0
  25. package/dist/config/index.d.ts +4 -0
  26. package/dist/config/index.d.ts.map +1 -0
  27. package/dist/config/index.js +4 -0
  28. package/dist/config/index.js.map +1 -0
  29. package/dist/config/loader.d.ts +8 -0
  30. package/dist/config/loader.d.ts.map +1 -0
  31. package/dist/config/loader.js +74 -0
  32. package/dist/config/loader.js.map +1 -0
  33. package/dist/config/paths.d.ts +9 -0
  34. package/dist/config/paths.d.ts.map +1 -0
  35. package/dist/config/paths.js +22 -0
  36. package/dist/config/paths.js.map +1 -0
  37. package/dist/hono-context.d.ts +14 -0
  38. package/dist/hono-context.d.ts.map +1 -0
  39. package/dist/hono-context.js +2 -0
  40. package/dist/hono-context.js.map +1 -0
  41. package/dist/index.js +64 -12
  42. package/dist/index.js.map +1 -1
  43. package/dist/keys/server-account.d.ts +28 -0
  44. package/dist/keys/server-account.d.ts.map +1 -0
  45. package/dist/keys/server-account.js +48 -0
  46. package/dist/keys/server-account.js.map +1 -0
  47. package/dist/logger/index.d.ts +5 -0
  48. package/dist/logger/index.d.ts.map +1 -0
  49. package/dist/logger/index.js +9 -0
  50. package/dist/logger/index.js.map +1 -0
  51. package/dist/logging/access-log.d.ts +15 -0
  52. package/dist/logging/access-log.d.ts.map +1 -0
  53. package/dist/logging/access-log.js +25 -0
  54. package/dist/logging/access-log.js.map +1 -0
  55. package/dist/logging/access-reader.d.ts +19 -0
  56. package/dist/logging/access-reader.d.ts.map +1 -0
  57. package/dist/logging/access-reader.js +50 -0
  58. package/dist/logging/access-reader.js.map +1 -0
  59. package/dist/middleware/access-log.d.ts.map +1 -1
  60. package/dist/middleware/access-log.js +8 -2
  61. package/dist/middleware/access-log.js.map +1 -1
  62. package/dist/middleware/builder-check.d.ts +2 -2
  63. package/dist/middleware/builder-check.d.ts.map +1 -1
  64. package/dist/middleware/builder-check.js +7 -2
  65. package/dist/middleware/builder-check.js.map +1 -1
  66. package/dist/middleware/owner-check.js +1 -1
  67. package/dist/middleware/owner-check.js.map +1 -1
  68. package/dist/middleware/web3-auth.d.ts +12 -0
  69. package/dist/middleware/web3-auth.d.ts.map +1 -1
  70. package/dist/middleware/web3-auth.js +27 -31
  71. package/dist/middleware/web3-auth.js.map +1 -1
  72. package/dist/migrations/local-state.d.ts +21 -0
  73. package/dist/migrations/local-state.d.ts.map +1 -0
  74. package/dist/migrations/local-state.js +106 -0
  75. package/dist/migrations/local-state.js.map +1 -0
  76. package/dist/routes/access-logs.d.ts +7 -0
  77. package/dist/routes/access-logs.d.ts.map +1 -1
  78. package/dist/routes/access-logs.js +11 -17
  79. package/dist/routes/access-logs.js.map +1 -1
  80. package/dist/routes/auth-device.d.ts +49 -0
  81. package/dist/routes/auth-device.d.ts.map +1 -0
  82. package/dist/routes/auth-device.js +581 -0
  83. package/dist/routes/auth-device.js.map +1 -0
  84. package/dist/routes/data.d.ts +42 -1
  85. package/dist/routes/data.d.ts.map +1 -1
  86. package/dist/routes/data.js +36 -201
  87. package/dist/routes/data.js.map +1 -1
  88. package/dist/routes/grants.d.ts +9 -2
  89. package/dist/routes/grants.d.ts.map +1 -1
  90. package/dist/routes/grants.js +18 -196
  91. package/dist/routes/grants.js.map +1 -1
  92. package/dist/routes/health.d.ts +7 -1
  93. package/dist/routes/health.d.ts.map +1 -1
  94. package/dist/routes/health.js +39 -2
  95. package/dist/routes/health.js.map +1 -1
  96. package/dist/routes/mcp.d.ts +93 -6
  97. package/dist/routes/mcp.d.ts.map +1 -1
  98. package/dist/routes/mcp.js +526 -53
  99. package/dist/routes/mcp.js.map +1 -1
  100. package/dist/routes/oauth-token.d.ts +56 -0
  101. package/dist/routes/oauth-token.d.ts.map +1 -0
  102. package/dist/routes/oauth-token.js +49 -0
  103. package/dist/routes/oauth-token.js.map +1 -0
  104. package/dist/routes/sync.d.ts +7 -0
  105. package/dist/routes/sync.d.ts.map +1 -1
  106. package/dist/routes/sync.js +12 -39
  107. package/dist/routes/sync.js.map +1 -1
  108. package/dist/routes/ui-config.d.ts.map +1 -1
  109. package/dist/routes/ui-config.js +17 -82
  110. package/dist/routes/ui-config.js.map +1 -1
  111. package/dist/routes/ui-registration.d.ts +9 -0
  112. package/dist/routes/ui-registration.d.ts.map +1 -0
  113. package/dist/routes/ui-registration.js +217 -0
  114. package/dist/routes/ui-registration.js.map +1 -0
  115. package/dist/routes/ui.d.ts +1 -0
  116. package/dist/routes/ui.d.ts.map +1 -1
  117. package/dist/routes/ui.js +46 -4
  118. package/dist/routes/ui.js.map +1 -1
  119. package/dist/storage/hierarchy.d.ts +29 -0
  120. package/dist/storage/hierarchy.d.ts.map +1 -0
  121. package/dist/storage/hierarchy.js +241 -0
  122. package/dist/storage/hierarchy.js.map +1 -0
  123. package/dist/storage/index-manager.d.ts +53 -0
  124. package/dist/storage/index-manager.d.ts.map +1 -0
  125. package/dist/storage/index-manager.js +167 -0
  126. package/dist/storage/index-manager.js.map +1 -0
  127. package/dist/storage/index-schema.d.ts +5 -0
  128. package/dist/storage/index-schema.d.ts.map +1 -0
  129. package/dist/storage/index-schema.js +62 -0
  130. package/dist/storage/index-schema.js.map +1 -0
  131. package/dist/storage/node-data-storage.d.ts +9 -0
  132. package/dist/storage/node-data-storage.d.ts.map +1 -0
  133. package/dist/storage/node-data-storage.js +84 -0
  134. package/dist/storage/node-data-storage.js.map +1 -0
  135. package/dist/sync-cursor.d.ts +15 -0
  136. package/dist/sync-cursor.d.ts.map +1 -0
  137. package/dist/sync-cursor.js +110 -0
  138. package/dist/sync-cursor.js.map +1 -0
  139. package/dist/token-store.d.ts +22 -0
  140. package/dist/token-store.d.ts.map +1 -0
  141. package/dist/token-store.js +120 -0
  142. package/dist/token-store.js.map +1 -0
  143. package/dist/tunnel/auth.d.ts +4 -0
  144. package/dist/tunnel/auth.d.ts.map +1 -1
  145. package/dist/tunnel/auth.js +2 -1
  146. package/dist/tunnel/auth.js.map +1 -1
  147. package/dist/tunnel/config.d.ts +1 -0
  148. package/dist/tunnel/config.d.ts.map +1 -1
  149. package/dist/tunnel/config.js +1 -1
  150. package/dist/tunnel/config.js.map +1 -1
  151. package/dist/tunnel/manager.d.ts +21 -1
  152. package/dist/tunnel/manager.d.ts.map +1 -1
  153. package/dist/tunnel/manager.js +78 -23
  154. package/dist/tunnel/manager.js.map +1 -1
  155. package/dist/tunnel/verify.d.ts +1 -1
  156. package/dist/tunnel/verify.d.ts.map +1 -1
  157. package/dist/tunnel/verify.js +8 -2
  158. package/dist/tunnel/verify.js.map +1 -1
  159. package/dist/ui/browser_tls_rustls_bg.wasm +0 -0
  160. package/dist/ui/index.html +2192 -0
  161. package/dist/ui/ps-lite-debug.d.ts +93 -0
  162. package/dist/ui/ps-lite-debug.d.ts.map +1 -0
  163. package/dist/ui/ps-lite-debug.js +129416 -0
  164. package/dist/ui/ps-lite-debug.js.map +1 -0
  165. package/package.json +20 -8
  166. package/dist/middleware/grant-check.d.ts +0 -12
  167. package/dist/middleware/grant-check.d.ts.map +0 -1
  168. package/dist/middleware/grant-check.js +0 -90
  169. package/dist/middleware/grant-check.js.map +0 -1
  170. package/dist/oauth/provider.d.ts +0 -55
  171. package/dist/oauth/provider.d.ts.map +0 -1
  172. package/dist/oauth/provider.js +0 -160
  173. package/dist/oauth/provider.js.map +0 -1
  174. package/dist/oauth/routes.d.ts +0 -10
  175. package/dist/oauth/routes.d.ts.map +0 -1
  176. package/dist/oauth/routes.js +0 -206
  177. package/dist/oauth/routes.js.map +0 -1
package/dist/routes/ui.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { readFileSync } from "node:fs";
2
- import { join, dirname } from "node:path";
2
+ import { join, dirname, sep } from "node:path";
3
3
  import { fileURLToPath } from "node:url";
4
4
  import { Hono } from "hono";
5
5
  // Read the HTML file once at module load time
@@ -8,17 +8,34 @@ function getHtmlPath() {
8
8
  const currentDir = dirname(fileURLToPath(import.meta.url));
9
9
  return join(currentDir, "..", "ui", "index.html");
10
10
  }
11
- function loadHtml(devToken) {
11
+ function getUiAssetPath(fileName) {
12
+ const currentDir = dirname(fileURLToPath(import.meta.url));
13
+ const distPath = join(currentDir, "..", "ui", fileName);
14
+ if (!currentDir.endsWith(`${sep}dist${sep}routes`)) {
15
+ return join(currentDir, "..", "..", "dist", "ui", fileName);
16
+ }
17
+ return distPath;
18
+ }
19
+ function loadHtml(devToken, psLiteBootstrap) {
12
20
  if (!cachedHtml) {
13
21
  cachedHtml = readFileSync(getHtmlPath(), "utf-8");
14
22
  }
15
- return cachedHtml.replace("__DEV_TOKEN__", devToken);
23
+ return cachedHtml
24
+ .replace("__DEV_TOKEN__", devToken)
25
+ .replace('"__PS_LITE_BOOTSTRAP_JSON__"', JSON.stringify(psLiteBootstrap ?? null));
26
+ }
27
+ function contentTypeFor(fileName) {
28
+ if (fileName.endsWith(".js"))
29
+ return "application/javascript; charset=utf-8";
30
+ if (fileName.endsWith(".wasm"))
31
+ return "application/wasm";
32
+ return "application/octet-stream";
16
33
  }
17
34
  export function uiRoute(deps) {
18
35
  const app = new Hono();
19
36
  app.get("/", (c) => {
20
37
  try {
21
- const html = loadHtml(deps.devToken);
38
+ const html = loadHtml(deps.devToken, deps.psLiteBootstrap);
22
39
  return c.html(html);
23
40
  }
24
41
  catch {
@@ -31,6 +48,31 @@ export function uiRoute(deps) {
31
48
  }, 500);
32
49
  }
33
50
  });
51
+ app.get("/:file", (c) => {
52
+ const fileName = c.req.param("file");
53
+ if (fileName !== "ps-lite-debug.js" &&
54
+ fileName !== "browser_tls_rustls_bg.wasm") {
55
+ return c.notFound();
56
+ }
57
+ try {
58
+ const asset = readFileSync(getUiAssetPath(fileName));
59
+ return new Response(asset, {
60
+ headers: {
61
+ "content-type": contentTypeFor(fileName),
62
+ "cache-control": "no-store",
63
+ },
64
+ });
65
+ }
66
+ catch {
67
+ return c.json({
68
+ error: {
69
+ code: 404,
70
+ errorCode: "UI_ASSET_NOT_FOUND",
71
+ message: "UI asset not found. Run npm run build.",
72
+ },
73
+ }, 404);
74
+ }
75
+ });
34
76
  return app;
35
77
  }
36
78
  //# sourceMappingURL=ui.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ui.js","sourceRoot":"","sources":["../../src/routes/ui.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAM5B,8CAA8C;AAC9C,IAAI,UAAU,GAAkB,IAAI,CAAC;AAErC,SAAS,WAAW;IAClB,MAAM,UAAU,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAC3D,OAAO,IAAI,CAAC,UAAU,EAAE,IAAI,EAAE,IAAI,EAAE,YAAY,CAAC,CAAC;AACpD,CAAC;AAED,SAAS,QAAQ,CAAC,QAAgB;IAChC,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,UAAU,GAAG,YAAY,CAAC,WAAW,EAAE,EAAE,OAAO,CAAC,CAAC;IACpD,CAAC;IACD,OAAO,UAAU,CAAC,OAAO,CAAC,eAAe,EAAE,QAAQ,CAAC,CAAC;AACvD,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,IAAiB;IACvC,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;IAEvB,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE;QACjB,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACrC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACtB,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,CAAC,IAAI,CACX;gBACE,KAAK,EAAE;oBACL,IAAI,EAAE,GAAG;oBACT,SAAS,EAAE,UAAU;oBACrB,OAAO,EAAE,mBAAmB;iBAC7B;aACF,EACD,GAAG,CACJ,CAAC;QACJ,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,GAAG,CAAC;AACb,CAAC"}
1
+ {"version":3,"file":"ui.js","sourceRoot":"","sources":["../../src/routes/ui.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ import { type DataFileEnvelope } from "@opendatalabs/vana-sdk/browser";
2
+ import { type HierarchyManagerOptions, type WriteResult } from "@opendatalabs/personal-server-ts-core/storage/hierarchy";
3
+ import { type DataBlockManifest, type DataScopeBlock, type ReadScopeBlocksResponse } from "@opendatalabs/personal-server-ts-core/storage/blocks";
4
+ /** Atomic write: mkdir -p, write temp file, rename */
5
+ export declare function writeDataFile(options: HierarchyManagerOptions, envelope: DataFileEnvelope): Promise<WriteResult>;
6
+ /** Read and parse a data file */
7
+ export declare function readDataFile(options: HierarchyManagerOptions, scope: string, collectedAt: string): Promise<DataFileEnvelope>;
8
+ /** Read a bounded UTF-8 text prefix without parsing the full envelope. */
9
+ export declare function readDataFilePreview(options: HierarchyManagerOptions, scope: string, collectedAt: string, maxBytes: number): Promise<{
10
+ text: string;
11
+ truncated: boolean;
12
+ }>;
13
+ export declare function writeBlockManifest(options: HierarchyManagerOptions, scope: string, collectedAt: string, manifest: DataBlockManifest, blocks: DataScopeBlock[]): Promise<void>;
14
+ export declare function readScopeBlocks(options: HierarchyManagerOptions, scope: string, collectedAt: string, readOptions: {
15
+ cursor?: string;
16
+ maxBytes: number;
17
+ }): Promise<ReadScopeBlocksResponse>;
18
+ export declare function hasScopeBlocks(options: HierarchyManagerOptions, scope: string, collectedAt: string): Promise<boolean>;
19
+ /** List version filenames for a scope, newest first. Empty array if scope dir doesn't exist. */
20
+ export declare function listVersions(options: HierarchyManagerOptions, scope: string): Promise<string[]>;
21
+ /** Delete a single data file. Idempotent: a missing file is a no-op (matches deleteByFileId's
22
+ * no-op contract and avoids stalling the sync cursor when the blob is already gone). */
23
+ export declare function deleteDataFile(options: HierarchyManagerOptions, scope: string, collectedAt: string): Promise<void>;
24
+ /**
25
+ * Delete all files for a scope by removing the scope directory recursively.
26
+ * No-op if directory doesn't exist.
27
+ */
28
+ export declare function deleteAllForScope(options: HierarchyManagerOptions, scope: string): Promise<void>;
29
+ //# sourceMappingURL=hierarchy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hierarchy.d.ts","sourceRoot":"","sources":["../../src/storage/hierarchy.ts"],"names":[],"mappings":"AAcA,OAAO,EAEL,KAAK,gBAAgB,EACtB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAIL,KAAK,uBAAuB,EAC5B,KAAK,WAAW,EACjB,MAAM,yDAAyD,CAAC;AACjE,OAAO,EAIL,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACnB,KAAK,uBAAuB,EAC7B,MAAM,sDAAsD,CAAC;AAO9D,sDAAsD;AACtD,wBAAsB,aAAa,CACjC,OAAO,EAAE,uBAAuB,EAChC,QAAQ,EAAE,gBAAgB,GACzB,OAAO,CAAC,WAAW,CAAC,CAuBtB;AAED,iCAAiC;AACjC,wBAAsB,YAAY,CAChC,OAAO,EAAE,uBAAuB,EAChC,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,gBAAgB,CAAC,CAI3B;AAED,0EAA0E;AAC1E,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,uBAAuB,EAChC,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CAAC,CAgB/C;AAED,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,uBAAuB,EAChC,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,iBAAiB,EAC3B,MAAM,EAAE,cAAc,EAAE,GACvB,OAAO,CAAC,IAAI,CAAC,CAiCf;AAED,wBAAsB,eAAe,CACnC,OAAO,EAAE,uBAAuB,EAChC,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GACjD,OAAO,CAAC,uBAAuB,CAAC,CAmElC;AAED,wBAAsB,cAAc,CAClC,OAAO,EAAE,uBAAuB,EAChC,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,OAAO,CAAC,CAUlB;AAED,gGAAgG;AAChG,wBAAsB,YAAY,CAChC,OAAO,EAAE,uBAAuB,EAChC,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,MAAM,EAAE,CAAC,CAmBnB;AAED;wFACwF;AACxF,wBAAsB,cAAc,CAClC,OAAO,EAAE,uBAAuB,EAChC,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,CAAC,CAQf;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,uBAAuB,EAChC,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,IAAI,CAAC,CAKf"}
@@ -0,0 +1,241 @@
1
+ import { access, mkdir, open, readFile, writeFile, readdir, unlink, rename, stat, rm, } from "node:fs/promises";
2
+ import { dirname, join, relative } from "node:path";
3
+ import { randomUUID } from "node:crypto";
4
+ import { DataFileEnvelopeSchema, } from "@opendatalabs/vana-sdk/browser";
5
+ import { buildDataFilePath, buildScopeDir, filenameToTimestamp, } from "@opendatalabs/personal-server-ts-core/storage/hierarchy";
6
+ import { DataBlockStorageError, encodeDataBlockCursor, validateDataBlockCursor, } from "@opendatalabs/personal-server-ts-core/storage/blocks";
7
+ import { previewJsonEnvelopePrefix } from "@opendatalabs/personal-server-ts-core/storage/preview";
8
+ const TEXT_PAGE_MEDIA_TYPE = "text/plain; charset=utf-8";
9
+ const textEncoder = new TextEncoder();
10
+ const textDecoder = new TextDecoder();
11
+ /** Atomic write: mkdir -p, write temp file, rename */
12
+ export async function writeDataFile(options, envelope) {
13
+ const filePath = buildDataFilePath(options.dataDir, envelope.scope, envelope.collectedAt);
14
+ const dir = dirname(filePath);
15
+ await mkdir(dir, { recursive: true });
16
+ const content = JSON.stringify(envelope, null, 2);
17
+ const tempPath = filePath + ".tmp." + randomUUID();
18
+ await writeFile(tempPath, content, "utf-8");
19
+ await rename(tempPath, filePath);
20
+ const stats = await stat(filePath);
21
+ return {
22
+ path: filePath,
23
+ relativePath: relative(options.dataDir, filePath),
24
+ sizeBytes: stats.size,
25
+ };
26
+ }
27
+ /** Read and parse a data file */
28
+ export async function readDataFile(options, scope, collectedAt) {
29
+ const filePath = buildDataFilePath(options.dataDir, scope, collectedAt);
30
+ const content = await readFile(filePath, "utf-8");
31
+ return DataFileEnvelopeSchema.parse(JSON.parse(content));
32
+ }
33
+ /** Read a bounded UTF-8 text prefix without parsing the full envelope. */
34
+ export async function readDataFilePreview(options, scope, collectedAt, maxBytes) {
35
+ const filePath = buildDataFilePath(options.dataDir, scope, collectedAt);
36
+ const handle = await open(filePath, "r");
37
+ try {
38
+ const stats = await handle.stat();
39
+ const bytesToRead = Math.max(0, Math.min(maxBytes, stats.size));
40
+ const buffer = Buffer.alloc(bytesToRead);
41
+ const { bytesRead } = await handle.read(buffer, 0, bytesToRead, 0);
42
+ return previewJsonEnvelopePrefix(buffer.subarray(0, bytesRead).toString("utf-8"), maxBytes, { sourceTruncated: stats.size > bytesRead });
43
+ }
44
+ finally {
45
+ await handle.close();
46
+ }
47
+ }
48
+ export async function writeBlockManifest(options, scope, collectedAt, manifest, blocks) {
49
+ const dir = buildBlockDir(options.dataDir, scope, collectedAt);
50
+ const tempDir = `${dir}.tmp.${randomUUID()}`;
51
+ await mkdir(tempDir, { recursive: true });
52
+ try {
53
+ for (const block of blocks) {
54
+ await writeFile(buildBlockPayloadPath(tempDir, block.id), JSON.stringify(block), "utf-8");
55
+ }
56
+ await rm(dir, { recursive: true, force: true });
57
+ await rename(tempDir, dir);
58
+ const manifestPath = buildBlockManifestPath(options.dataDir, scope, collectedAt);
59
+ const tempManifestPath = `${manifestPath}.tmp.${randomUUID()}`;
60
+ await writeFile(tempManifestPath, JSON.stringify(manifest, null, 2), "utf-8");
61
+ await rename(tempManifestPath, manifestPath);
62
+ }
63
+ catch (err) {
64
+ await rm(tempDir, { recursive: true, force: true });
65
+ throw err;
66
+ }
67
+ }
68
+ export async function readScopeBlocks(options, scope, collectedAt, readOptions) {
69
+ const manifest = await readBlockManifest(options, scope, collectedAt);
70
+ const cursor = readOptions.cursor
71
+ ? validateDataBlockCursor(readOptions.cursor, { scope, collectedAt })
72
+ : undefined;
73
+ if (cursor && !cursor.ok) {
74
+ throw new DataBlockStorageError("cursor_invalid", cursor.error.message);
75
+ }
76
+ const maxBytes = Math.max(1, readOptions.maxBytes);
77
+ const startIndex = cursor?.ok ? cursor.cursor.blockIndex : 0;
78
+ const startOffset = cursor?.ok ? (cursor.cursor.intraBlockOffset ?? 0) : 0;
79
+ const blocks = [];
80
+ let totalBytes = 0;
81
+ let nextIndex = startIndex;
82
+ let nextOffset;
83
+ while (nextIndex < manifest.blocks.length) {
84
+ const ref = manifest.blocks[nextIndex];
85
+ const offset = nextIndex === startIndex ? startOffset : 0;
86
+ if (offset >= ref.sizeBytes) {
87
+ nextIndex++;
88
+ continue;
89
+ }
90
+ if (blocks.length > 0 &&
91
+ offset === 0 &&
92
+ totalBytes + ref.sizeBytes > maxBytes)
93
+ break;
94
+ const block = await readBlockPayload(options, scope, collectedAt, ref.id);
95
+ const page = pageBlock(block, offset, maxBytes - totalBytes);
96
+ blocks.push(page.block);
97
+ totalBytes += page.block.sizeBytes;
98
+ if (page.nextOffset !== undefined) {
99
+ nextOffset = page.nextOffset;
100
+ break;
101
+ }
102
+ nextIndex++;
103
+ if (totalBytes >= maxBytes)
104
+ break;
105
+ }
106
+ return {
107
+ scope: manifest.scope,
108
+ collectedAt: manifest.collectedAt,
109
+ ...(manifest.schemaId ? { schemaId: manifest.schemaId } : {}),
110
+ contentKind: manifest.contentKind,
111
+ blocks,
112
+ ...(nextOffset !== undefined || nextIndex < manifest.blocks.length
113
+ ? {
114
+ nextCursor: encodeDataBlockCursor({
115
+ scope,
116
+ collectedAt,
117
+ blockIndex: nextIndex,
118
+ ...(nextOffset === undefined
119
+ ? {}
120
+ : { intraBlockOffset: nextOffset }),
121
+ }),
122
+ }
123
+ : {}),
124
+ warnings: manifest.warnings,
125
+ };
126
+ }
127
+ export async function hasScopeBlocks(options, scope, collectedAt) {
128
+ try {
129
+ await access(buildBlockManifestPath(options.dataDir, scope, collectedAt));
130
+ return true;
131
+ }
132
+ catch (err) {
133
+ if (err.code === "ENOENT") {
134
+ return false;
135
+ }
136
+ throw err;
137
+ }
138
+ }
139
+ /** List version filenames for a scope, newest first. Empty array if scope dir doesn't exist. */
140
+ export async function listVersions(options, scope) {
141
+ const scopeDir = buildScopeDir(options.dataDir, scope);
142
+ let entries;
143
+ try {
144
+ entries = await readdir(scopeDir);
145
+ }
146
+ catch (err) {
147
+ if (err.code === "ENOENT") {
148
+ return [];
149
+ }
150
+ throw err;
151
+ }
152
+ const jsonFiles = entries
153
+ .filter((f) => f.endsWith(".json"))
154
+ .sort()
155
+ .reverse();
156
+ return jsonFiles.map((f) => filenameToTimestamp(f.replace(".json", "")));
157
+ }
158
+ /** Delete a single data file. Idempotent: a missing file is a no-op (matches deleteByFileId's
159
+ * no-op contract and avoids stalling the sync cursor when the blob is already gone). */
160
+ export async function deleteDataFile(options, scope, collectedAt) {
161
+ const filePath = buildDataFilePath(options.dataDir, scope, collectedAt);
162
+ try {
163
+ await unlink(filePath);
164
+ }
165
+ catch (err) {
166
+ if (err.code !== "ENOENT")
167
+ throw err;
168
+ }
169
+ await deleteBlockSidecars(options, scope, collectedAt);
170
+ }
171
+ /**
172
+ * Delete all files for a scope by removing the scope directory recursively.
173
+ * No-op if directory doesn't exist.
174
+ */
175
+ export async function deleteAllForScope(options, scope) {
176
+ const scopeDir = buildScopeDir(options.dataDir, scope);
177
+ await rm(scopeDir, { recursive: true, force: true });
178
+ const blockScopeDir = buildScopeDir(join(options.dataDir, "blocks"), scope);
179
+ await rm(blockScopeDir, { recursive: true, force: true });
180
+ }
181
+ async function readBlockManifest(options, scope, collectedAt) {
182
+ try {
183
+ return JSON.parse(await readFile(buildBlockManifestPath(options.dataDir, scope, collectedAt), "utf-8"));
184
+ }
185
+ catch (err) {
186
+ if (err.code === "ENOENT") {
187
+ throw new DataBlockStorageError("block_manifest_not_found", `Block manifest not found for ${scope} at ${collectedAt}`);
188
+ }
189
+ throw err;
190
+ }
191
+ }
192
+ async function readBlockPayload(options, scope, collectedAt, blockId) {
193
+ try {
194
+ return JSON.parse(await readFile(buildBlockPayloadPath(buildBlockDir(options.dataDir, scope, collectedAt), blockId), "utf-8"));
195
+ }
196
+ catch (err) {
197
+ if (err.code === "ENOENT") {
198
+ throw new DataBlockStorageError("block_payload_not_found", `Block payload not found for ${scope} at ${collectedAt}: ${blockId}`);
199
+ }
200
+ throw err;
201
+ }
202
+ }
203
+ function pageBlock(block, offsetBytes, maxBytes) {
204
+ const text = typeof block.value === "string" ? block.value : JSON.stringify(block.value);
205
+ const bytes = textEncoder.encode(text);
206
+ if (offsetBytes <= 0 && bytes.length <= maxBytes) {
207
+ return { block };
208
+ }
209
+ const start = Math.min(Math.max(0, offsetBytes), bytes.length);
210
+ const end = Math.min(bytes.length, start + Math.max(1, maxBytes));
211
+ const value = textDecoder.decode(bytes.slice(start, end));
212
+ return {
213
+ block: {
214
+ ...block,
215
+ path: `${block.path}[bytes ${start}:${end}]`,
216
+ mediaType: block.mediaType.startsWith("text/")
217
+ ? block.mediaType
218
+ : TEXT_PAGE_MEDIA_TYPE,
219
+ value,
220
+ sizeBytes: end - start,
221
+ truncated: end < bytes.length,
222
+ },
223
+ ...(end < bytes.length ? { nextOffset: end } : {}),
224
+ };
225
+ }
226
+ async function deleteBlockSidecars(options, scope, collectedAt) {
227
+ await rm(buildBlockDir(options.dataDir, scope, collectedAt), {
228
+ recursive: true,
229
+ force: true,
230
+ });
231
+ }
232
+ function buildBlockDir(dataDir, scope, collectedAt) {
233
+ return join(buildScopeDir(join(dataDir, "blocks"), scope), collectedAt);
234
+ }
235
+ function buildBlockManifestPath(dataDir, scope, collectedAt) {
236
+ return join(buildBlockDir(dataDir, scope, collectedAt), "manifest.json");
237
+ }
238
+ function buildBlockPayloadPath(dir, blockId) {
239
+ return join(dir, `${encodeURIComponent(blockId)}.json`);
240
+ }
241
+ //# sourceMappingURL=hierarchy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hierarchy.js","sourceRoot":"","sources":["../../src/storage/hierarchy.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ import type Database from "better-sqlite3";
2
+ import type { IndexEntry, IndexListOptions, NewIndexEntry, ScopeSummary } from "@opendatalabs/personal-server-ts-core/storage/index";
3
+ export interface IndexManager {
4
+ insert(entry: NewIndexEntry): IndexEntry;
5
+ findByPath(path: string): IndexEntry | undefined;
6
+ findByScope(options: IndexListOptions): IndexEntry[];
7
+ findLatestByScope(scope: string): IndexEntry | undefined;
8
+ countByScope(scope: string): number;
9
+ deleteByPath(path: string): boolean;
10
+ listDistinctScopes(options?: {
11
+ scopePrefix?: string;
12
+ limit?: number;
13
+ offset?: number;
14
+ }): {
15
+ scopes: ScopeSummary[];
16
+ total: number;
17
+ };
18
+ findClosestByScope(scope: string, at: string): IndexEntry | undefined;
19
+ findByFileId(fileId: string): IndexEntry | undefined;
20
+ /** Find an index entry by its DPv2 data-point id (download dedup). */
21
+ findByDataPointId(dataPointId: string): IndexEntry | undefined;
22
+ /**
23
+ * Find all index entries where dataPointId is null (not yet synced /
24
+ * registered on-chain). Returns entries ordered by created_at ASC (oldest
25
+ * first).
26
+ */
27
+ findUnsynced(options?: {
28
+ limit?: number;
29
+ }): IndexEntry[];
30
+ /**
31
+ * Update the fileId for an index entry (after successful upload + on-chain registration).
32
+ * @returns true if row was updated, false if path not found
33
+ */
34
+ updateFileId(path: string, fileId: string): boolean;
35
+ /** Highest stored `version` for a scope; 0 if none. */
36
+ findLatestVersionByScope(scope: string): number;
37
+ /**
38
+ * Update the dataPointId for an index entry (after DPv2 registerDataPoint).
39
+ * @returns true if row was updated, false if path not found
40
+ */
41
+ updateDataPointId(path: string, dataPointId: string): boolean;
42
+ /**
43
+ * Update the DPv2 `version` for an index entry (upload-worker rebase after
44
+ * a stale-expectedVersion conflict).
45
+ * @returns true if row was updated, false if path not found
46
+ */
47
+ updateVersion(path: string, version: number): boolean;
48
+ /** Deletes all index entries for a scope. Returns count of deleted rows. */
49
+ deleteByScope(scope: string): number;
50
+ close(): void;
51
+ }
52
+ export declare function createIndexManager(db: Database.Database): IndexManager;
53
+ //# sourceMappingURL=index-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-manager.d.ts","sourceRoot":"","sources":["../../src/storage/index-manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAC3C,OAAO,KAAK,EACV,UAAU,EACV,gBAAgB,EAChB,aAAa,EACb,YAAY,EACb,MAAM,qDAAqD,CAAC;AAE7D,MAAM,WAAW,YAAY;IAC3B,MAAM,CAAC,KAAK,EAAE,aAAa,GAAG,UAAU,CAAC;IACzC,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAAC;IACjD,WAAW,CAAC,OAAO,EAAE,gBAAgB,GAAG,UAAU,EAAE,CAAC;IACrD,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAAC;IACzD,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IACpC,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IACpC,kBAAkB,CAAC,OAAO,CAAC,EAAE;QAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,GAAG;QAAE,MAAM,EAAE,YAAY,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9C,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAAC;IACtE,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAAC;IACrD,sEAAsE;IACtE,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAAC;IAC/D;;;;OAIG;IACH,YAAY,CAAC,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,UAAU,EAAE,CAAC;IACzD;;;OAGG;IACH,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;IACpD,uDAAuD;IACvD,wBAAwB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IAChD;;;OAGG;IACH,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC;IAC9D;;;;OAIG;IACH,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;IACtD,4EAA4E;IAC5E,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IACrC,KAAK,IAAI,IAAI,CAAC;CACf;AA8BD,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,GAAG,YAAY,CA0PtE"}
@@ -0,0 +1,167 @@
1
+ function rowToEntry(row) {
2
+ return {
3
+ id: row.id,
4
+ fileId: row.file_id,
5
+ schemaId: row.schema_id,
6
+ path: row.path,
7
+ scope: row.scope,
8
+ collectedAt: row.collected_at,
9
+ createdAt: row.created_at,
10
+ sizeBytes: row.size_bytes,
11
+ version: row.version,
12
+ dataPointId: row.data_point_id,
13
+ };
14
+ }
15
+ export function createIndexManager(db) {
16
+ const insertStmt = db.prepare(`INSERT INTO data_files (file_id, schema_id, path, scope, collected_at, size_bytes, version, data_point_id)
17
+ VALUES (@file_id, @schema_id, @path, @scope, @collected_at, @size_bytes, @version, @data_point_id)`);
18
+ const maxVersionByScopeStmt = db.prepare("SELECT COALESCE(MAX(version), 0) AS max_version FROM data_files WHERE scope = @scope");
19
+ const findByPathStmt = db.prepare("SELECT * FROM data_files WHERE path = @path");
20
+ const findLatestByScopeStmt = db.prepare("SELECT * FROM data_files WHERE scope = @scope ORDER BY collected_at DESC LIMIT 1");
21
+ const countByScopeStmt = db.prepare("SELECT COUNT(*) AS cnt FROM data_files WHERE scope = @scope");
22
+ const deleteByPathStmt = db.prepare("DELETE FROM data_files WHERE path = @path");
23
+ const findClosestByScopeStmt = db.prepare("SELECT * FROM data_files WHERE scope = @scope AND collected_at <= @at ORDER BY collected_at DESC LIMIT 1");
24
+ const findByFileIdStmt = db.prepare("SELECT * FROM data_files WHERE file_id = @file_id");
25
+ const findByDataPointIdStmt = db.prepare("SELECT * FROM data_files WHERE data_point_id = @data_point_id");
26
+ const findUnsyncedStmt = db.prepare("SELECT * FROM data_files WHERE data_point_id IS NULL ORDER BY created_at ASC");
27
+ const findUnsyncedLimitStmt = db.prepare("SELECT * FROM data_files WHERE data_point_id IS NULL ORDER BY created_at ASC LIMIT @limit");
28
+ const updateFileIdStmt = db.prepare("UPDATE data_files SET file_id = @file_id WHERE path = @path");
29
+ const updateDataPointIdStmt = db.prepare("UPDATE data_files SET data_point_id = @data_point_id WHERE path = @path");
30
+ const updateVersionStmt = db.prepare("UPDATE data_files SET version = @version WHERE path = @path");
31
+ const deleteByScopeStmt = db.prepare("DELETE FROM data_files WHERE scope = @scope");
32
+ return {
33
+ insert(entry) {
34
+ // Caller-supplied version wins; otherwise advance the per-scope
35
+ // counter atomically inside the same statement chain.
36
+ const version = entry.version ??
37
+ maxVersionByScopeStmt.get({ scope: entry.scope }).max_version + 1;
38
+ const result = insertStmt.run({
39
+ file_id: entry.fileId,
40
+ schema_id: entry.schemaId ?? null,
41
+ path: entry.path,
42
+ scope: entry.scope,
43
+ collected_at: entry.collectedAt,
44
+ size_bytes: entry.sizeBytes,
45
+ version,
46
+ data_point_id: entry.dataPointId ?? null,
47
+ });
48
+ const row = db
49
+ .prepare("SELECT * FROM data_files WHERE id = ?")
50
+ .get(result.lastInsertRowid);
51
+ return rowToEntry(row);
52
+ },
53
+ findByPath(path) {
54
+ const row = findByPathStmt.get({ path });
55
+ return row ? rowToEntry(row) : undefined;
56
+ },
57
+ findByScope(options) {
58
+ let sql = "SELECT * FROM data_files";
59
+ const params = {};
60
+ if (options.scope) {
61
+ sql += " WHERE scope = @scope";
62
+ params.scope = options.scope;
63
+ }
64
+ // id is the autoincrement PK — a stable tiebreaker so limit/offset paging can't skip or
65
+ // duplicate rows when versions share a collected_at (second precision).
66
+ sql += " ORDER BY collected_at DESC, id DESC";
67
+ if (options.limit !== undefined) {
68
+ sql += " LIMIT @limit";
69
+ params.limit = options.limit;
70
+ }
71
+ if (options.offset !== undefined) {
72
+ sql += " OFFSET @offset";
73
+ params.offset = options.offset;
74
+ }
75
+ const rows = db.prepare(sql).all(params);
76
+ return rows.map(rowToEntry);
77
+ },
78
+ findLatestByScope(scope) {
79
+ const row = findLatestByScopeStmt.get({ scope });
80
+ return row ? rowToEntry(row) : undefined;
81
+ },
82
+ countByScope(scope) {
83
+ const row = countByScopeStmt.get({ scope });
84
+ return row.cnt;
85
+ },
86
+ deleteByPath(path) {
87
+ const result = deleteByPathStmt.run({ path });
88
+ return result.changes > 0;
89
+ },
90
+ listDistinctScopes(options) {
91
+ const hasPrefix = options?.scopePrefix !== undefined && options.scopePrefix !== "";
92
+ const prefix = hasPrefix ? options.scopePrefix + "%" : "%";
93
+ const countRow = db
94
+ .prepare("SELECT COUNT(DISTINCT scope) AS cnt FROM data_files WHERE scope LIKE @prefix")
95
+ .get({ prefix });
96
+ const total = countRow.cnt;
97
+ let sql = "SELECT scope, MAX(collected_at) AS latest_collected_at, COUNT(*) AS version_count FROM data_files WHERE scope LIKE @prefix GROUP BY scope ORDER BY scope ASC";
98
+ const params = { prefix };
99
+ if (options?.limit !== undefined) {
100
+ sql += " LIMIT @limit";
101
+ params.limit = options.limit;
102
+ }
103
+ if (options?.offset !== undefined) {
104
+ sql += " OFFSET @offset";
105
+ params.offset = options.offset;
106
+ }
107
+ const rows = db.prepare(sql).all(params);
108
+ return {
109
+ scopes: rows.map((r) => ({
110
+ scope: r.scope,
111
+ latestCollectedAt: r.latest_collected_at,
112
+ versionCount: r.version_count,
113
+ })),
114
+ total,
115
+ };
116
+ },
117
+ findClosestByScope(scope, at) {
118
+ const row = findClosestByScopeStmt.get({ scope, at });
119
+ return row ? rowToEntry(row) : undefined;
120
+ },
121
+ findByFileId(fileId) {
122
+ const row = findByFileIdStmt.get({ file_id: fileId });
123
+ return row ? rowToEntry(row) : undefined;
124
+ },
125
+ findByDataPointId(dataPointId) {
126
+ const row = findByDataPointIdStmt.get({ data_point_id: dataPointId });
127
+ return row ? rowToEntry(row) : undefined;
128
+ },
129
+ findUnsynced(options) {
130
+ if (options?.limit !== undefined) {
131
+ const rows = findUnsyncedLimitStmt.all({
132
+ limit: options.limit,
133
+ });
134
+ return rows.map(rowToEntry);
135
+ }
136
+ const rows = findUnsyncedStmt.all();
137
+ return rows.map(rowToEntry);
138
+ },
139
+ updateFileId(path, fileId) {
140
+ const result = updateFileIdStmt.run({ file_id: fileId, path });
141
+ return result.changes > 0;
142
+ },
143
+ findLatestVersionByScope(scope) {
144
+ const row = maxVersionByScopeStmt.get({ scope });
145
+ return row.max_version;
146
+ },
147
+ updateDataPointId(path, dataPointId) {
148
+ const result = updateDataPointIdStmt.run({
149
+ data_point_id: dataPointId,
150
+ path,
151
+ });
152
+ return result.changes > 0;
153
+ },
154
+ updateVersion(path, version) {
155
+ const result = updateVersionStmt.run({ version, path });
156
+ return result.changes > 0;
157
+ },
158
+ deleteByScope(scope) {
159
+ const result = deleteByScopeStmt.run({ scope });
160
+ return result.changes;
161
+ },
162
+ close() {
163
+ db.close();
164
+ },
165
+ };
166
+ }
167
+ //# sourceMappingURL=index-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-manager.js","sourceRoot":"","sources":["../../src/storage/index-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import Database from "better-sqlite3";
2
+ export declare const INDEX_SCHEMA_VERSION = 3;
3
+ /** Open/create SQLite database, run CREATE TABLE IF NOT EXISTS, set WAL mode */
4
+ export declare function initializeDatabase(dbPath: string): Database.Database;
5
+ //# sourceMappingURL=index-schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-schema.d.ts","sourceRoot":"","sources":["../../src/storage/index-schema.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AAwBtC,eAAO,MAAM,oBAAoB,IAAI,CAAC;AAyCtC,gFAAgF;AAChF,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,CAAC,QAAQ,CAYpE"}