@hasna/economy 0.3.28 → 0.5.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 (216) hide show
  1. package/CHANGELOG.md +119 -0
  2. package/CONTRIBUTING.md +1 -1
  3. package/README.md +18 -22
  4. package/SECURITY.md +1 -1
  5. package/dist/chunks/agent-registry-store-tpnhx3wj.js +39 -0
  6. package/dist/chunks/billing-bkpxy4kv.js +13 -0
  7. package/dist/chunks/config-j9mv3ehk.js +15 -0
  8. package/dist/chunks/index-2hwzmfgv.js +3407 -0
  9. package/dist/chunks/index-axh32d30.js +1313 -0
  10. package/dist/chunks/index-emvs5ph2.js +2085 -0
  11. package/dist/chunks/index-ez9thsr7.js +3440 -0
  12. package/dist/chunks/index-hesxq90g.js +62 -0
  13. package/dist/chunks/index-k540hfww.js +258 -0
  14. package/dist/chunks/index-kgy9b6bf.js +451 -0
  15. package/dist/chunks/index-kn5572kd.js +124 -0
  16. package/dist/chunks/index-p35cyhc4.js +4 -0
  17. package/dist/chunks/index-w3bvv0ns.js +26 -0
  18. package/dist/chunks/index-zpvea08j.js +3372 -0
  19. package/dist/chunks/menubar-6xtkt17h.js +296 -0
  20. package/dist/chunks/open-projects-6z4pq6mx.js +39 -0
  21. package/dist/chunks/pricing-f80p81gr.js +29 -0
  22. package/dist/chunks/pricing-vf2pycmh.js +30 -0
  23. package/dist/chunks/pricing-y21mcjsa.js +30 -0
  24. package/dist/chunks/serve-0k69e4h9.js +4655 -0
  25. package/dist/chunks/sqlite-store-501f32ts.js +258 -0
  26. package/dist/chunks/sqlite-store-fq4natnf.js +256 -0
  27. package/dist/chunks/sqlite-store-st99garx.js +258 -0
  28. package/dist/chunks/third-party-sqlite-5e85fxa2.js +11 -0
  29. package/dist/chunks/tui-7f8f951w.js +22 -0
  30. package/dist/chunks/watch-mm1j39vy.js +196 -0
  31. package/dist/chunks/webhooks-k4fh2t9c.js +109 -0
  32. package/dist/cli/commands/brief.d.ts.map +1 -1
  33. package/dist/cli/commands/extras.d.ts.map +1 -1
  34. package/dist/cli/commands/journal.d.ts +3 -0
  35. package/dist/cli/commands/journal.d.ts.map +1 -0
  36. package/dist/cli/commands/menubar.d.ts +97 -4
  37. package/dist/cli/commands/menubar.d.ts.map +1 -1
  38. package/dist/cli/commands/tui.d.ts +1 -1
  39. package/dist/cli/commands/tui.d.ts.map +1 -1
  40. package/dist/cli/commands/watch.d.ts.map +1 -1
  41. package/dist/cli/index.js +1524 -9998
  42. package/dist/db/cloud.d.ts +18 -12
  43. package/dist/db/cloud.d.ts.map +1 -1
  44. package/dist/db/database.d.ts +33 -12
  45. package/dist/db/database.d.ts.map +1 -1
  46. package/dist/db/ingest-concurrency-worker.d.ts +2 -0
  47. package/dist/db/ingest-concurrency-worker.d.ts.map +1 -0
  48. package/dist/db/ingest-errors.d.ts +9 -0
  49. package/dist/db/ingest-errors.d.ts.map +1 -0
  50. package/dist/db/ingest-schema.d.ts +3 -0
  51. package/dist/db/ingest-schema.d.ts.map +1 -0
  52. package/dist/db/ingest-specs.d.ts +8 -0
  53. package/dist/db/ingest-specs.d.ts.map +1 -0
  54. package/dist/db/ingest-test-contract.d.ts +3 -0
  55. package/dist/db/ingest-test-contract.d.ts.map +1 -0
  56. package/dist/db/ingest-validation.d.ts +12 -0
  57. package/dist/db/ingest-validation.d.ts.map +1 -0
  58. package/dist/db/ingest.d.ts +27 -0
  59. package/dist/db/ingest.d.ts.map +1 -0
  60. package/dist/db/legacy-schema.d.ts +7 -0
  61. package/dist/db/legacy-schema.d.ts.map +1 -0
  62. package/dist/db/observation-contract.d.ts +3 -0
  63. package/dist/db/observation-contract.d.ts.map +1 -0
  64. package/dist/db/observation-provenance.d.ts +23 -0
  65. package/dist/db/observation-provenance.d.ts.map +1 -0
  66. package/dist/db/observation-schema.d.ts +24 -0
  67. package/dist/db/observation-schema.d.ts.map +1 -0
  68. package/dist/db/pg-connection.d.ts +10 -0
  69. package/dist/db/pg-connection.d.ts.map +1 -0
  70. package/dist/db/pg-migrate.d.ts +4 -9
  71. package/dist/db/pg-migrate.d.ts.map +1 -1
  72. package/dist/db/pg-migrations.d.ts.map +1 -1
  73. package/dist/db/pg-protocol.d.ts +28 -0
  74. package/dist/db/pg-protocol.d.ts.map +1 -0
  75. package/dist/db/sqlite-store.d.ts +4 -0
  76. package/dist/db/sqlite-store.d.ts.map +1 -0
  77. package/dist/db/sync-pg.d.ts +17 -21
  78. package/dist/db/sync-pg.d.ts.map +1 -1
  79. package/dist/db/third-party-sqlite.d.ts +10 -0
  80. package/dist/db/third-party-sqlite.d.ts.map +1 -0
  81. package/dist/index.d.ts +3 -0
  82. package/dist/index.d.ts.map +1 -1
  83. package/dist/index.js +1281 -2405
  84. package/dist/ingest/claude-quota.d.ts.map +1 -1
  85. package/dist/ingest/claude.d.ts.map +1 -1
  86. package/dist/ingest/codex-quota.d.ts.map +1 -1
  87. package/dist/ingest/codex.d.ts +25 -0
  88. package/dist/ingest/codex.d.ts.map +1 -1
  89. package/dist/ingest/collection-outcome.d.ts +17 -0
  90. package/dist/ingest/collection-outcome.d.ts.map +1 -0
  91. package/dist/ingest/cursor.d.ts.map +1 -1
  92. package/dist/ingest/gemini.d.ts.map +1 -1
  93. package/dist/ingest/hermes.d.ts +1 -1
  94. package/dist/ingest/hermes.d.ts.map +1 -1
  95. package/dist/ingest/loops.d.ts +9 -0
  96. package/dist/ingest/loops.d.ts.map +1 -1
  97. package/dist/ingest/opencode.d.ts +1 -1
  98. package/dist/ingest/opencode.d.ts.map +1 -1
  99. package/dist/ingest/pi.d.ts +1 -1
  100. package/dist/ingest/pi.d.ts.map +1 -1
  101. package/dist/ingest/quota-observation.d.ts +16 -0
  102. package/dist/ingest/quota-observation.d.ts.map +1 -0
  103. package/dist/ingest/source-time.d.ts +4 -0
  104. package/dist/ingest/source-time.d.ts.map +1 -0
  105. package/dist/lib/accounts-store.d.ts +109 -0
  106. package/dist/lib/accounts-store.d.ts.map +1 -0
  107. package/dist/lib/accounts.d.ts +2 -1
  108. package/dist/lib/accounts.d.ts.map +1 -1
  109. package/dist/lib/analytics.d.ts.map +1 -1
  110. package/dist/lib/api-display-url.d.ts +19 -0
  111. package/dist/lib/api-display-url.d.ts.map +1 -0
  112. package/dist/lib/autosync-gate.d.ts +22 -0
  113. package/dist/lib/autosync-gate.d.ts.map +1 -0
  114. package/dist/lib/billing-diff.d.ts +18 -40
  115. package/dist/lib/billing-diff.d.ts.map +1 -1
  116. package/dist/lib/brief.d.ts +2 -0
  117. package/dist/lib/brief.d.ts.map +1 -1
  118. package/dist/lib/budget-decimal.d.ts +14 -0
  119. package/dist/lib/budget-decimal.d.ts.map +1 -0
  120. package/dist/lib/cloud-ingest.d.ts +30 -1
  121. package/dist/lib/cloud-ingest.d.ts.map +1 -1
  122. package/dist/lib/cloud-storage.d.ts +166 -10
  123. package/dist/lib/cloud-storage.d.ts.map +1 -1
  124. package/dist/lib/gatherer.d.ts.map +1 -1
  125. package/dist/lib/ingest-batches.d.ts +21 -0
  126. package/dist/lib/ingest-batches.d.ts.map +1 -0
  127. package/dist/lib/ingest-journal-client.d.ts +37 -0
  128. package/dist/lib/ingest-journal-client.d.ts.map +1 -0
  129. package/dist/lib/ingest-journal-lock.d.ts +5 -0
  130. package/dist/lib/ingest-journal-lock.d.ts.map +1 -0
  131. package/dist/lib/ingest-journal-maintenance.d.ts +92 -0
  132. package/dist/lib/ingest-journal-maintenance.d.ts.map +1 -0
  133. package/dist/lib/ingest-journal-operation.d.ts +55 -0
  134. package/dist/lib/ingest-journal-operation.d.ts.map +1 -0
  135. package/dist/lib/ingest-journal.d.ts +73 -0
  136. package/dist/lib/ingest-journal.d.ts.map +1 -0
  137. package/dist/lib/money-display.d.ts +13 -0
  138. package/dist/lib/money-display.d.ts.map +1 -0
  139. package/dist/lib/periods.d.ts +12 -0
  140. package/dist/lib/periods.d.ts.map +1 -1
  141. package/dist/lib/pricing.d.ts +14 -0
  142. package/dist/lib/pricing.d.ts.map +1 -1
  143. package/dist/lib/savings.d.ts +64 -7
  144. package/dist/lib/savings.d.ts.map +1 -1
  145. package/dist/lib/serve-auth.d.ts.map +1 -1
  146. package/dist/lib/store/index.d.ts +29 -22
  147. package/dist/lib/store/index.d.ts.map +1 -1
  148. package/dist/lib/summary-contract.d.ts +32 -0
  149. package/dist/lib/summary-contract.d.ts.map +1 -0
  150. package/dist/lib/summary-test-contract.d.ts +3 -0
  151. package/dist/lib/summary-test-contract.d.ts.map +1 -0
  152. package/dist/lib/sync-all.d.ts +4 -0
  153. package/dist/lib/sync-all.d.ts.map +1 -1
  154. package/dist/lib/sync-maintenance.d.ts.map +1 -1
  155. package/dist/lib/sync-report.d.ts +4 -0
  156. package/dist/lib/sync-report.d.ts.map +1 -0
  157. package/dist/lib/test-keychain-fixture.d.ts +9 -0
  158. package/dist/lib/test-keychain-fixture.d.ts.map +1 -0
  159. package/dist/mcp/agent-registry-store.d.ts +30 -0
  160. package/dist/mcp/agent-registry-store.d.ts.map +1 -0
  161. package/dist/mcp/agent-registry.d.ts +78 -0
  162. package/dist/mcp/agent-registry.d.ts.map +1 -0
  163. package/dist/mcp/harness.d.ts +26 -0
  164. package/dist/mcp/harness.d.ts.map +1 -0
  165. package/dist/mcp/index.js +3219 -3357
  166. package/dist/mcp/ingest-journal-tool.d.ts +2 -0
  167. package/dist/mcp/ingest-journal-tool.d.ts.map +1 -0
  168. package/dist/mcp/server.d.ts.map +1 -1
  169. package/dist/openapi.d.ts.map +1 -1
  170. package/dist/otel/index.js +2197 -121
  171. package/dist/server/human-auth.d.ts +20 -0
  172. package/dist/server/human-auth.d.ts.map +1 -0
  173. package/dist/server/index.js +10477 -6378
  174. package/dist/server/legacy-inventory.d.ts +52 -0
  175. package/dist/server/legacy-inventory.d.ts.map +1 -0
  176. package/dist/server/legacy-operations.d.ts +64 -0
  177. package/dist/server/legacy-operations.d.ts.map +1 -0
  178. package/dist/server/legacy-plan.d.ts +55 -0
  179. package/dist/server/legacy-plan.d.ts.map +1 -0
  180. package/dist/server/legacy-preservation.d.ts +58 -0
  181. package/dist/server/legacy-preservation.d.ts.map +1 -0
  182. package/dist/server/pg-sync-worker.js +195 -21
  183. package/dist/server/serve.d.ts +20 -18
  184. package/dist/server/serve.d.ts.map +1 -1
  185. package/dist/server/service-admission.d.ts +10 -0
  186. package/dist/server/service-admission.d.ts.map +1 -0
  187. package/dist/server/service-dispatcher.d.ts +45 -0
  188. package/dist/server/service-dispatcher.d.ts.map +1 -0
  189. package/dist/server/service-operations.d.ts +5 -0
  190. package/dist/server/service-operations.d.ts.map +1 -0
  191. package/dist/server/service-protocol.d.ts +50 -0
  192. package/dist/server/service-protocol.d.ts.map +1 -0
  193. package/dist/server/service-worker.d.ts +2 -0
  194. package/dist/server/service-worker.d.ts.map +1 -0
  195. package/dist/server/service-worker.js +8029 -0
  196. package/dist/types/index.d.ts +66 -0
  197. package/dist/types/index.d.ts.map +1 -1
  198. package/docs/README.md +1 -1
  199. package/docs/cli.md +2 -3
  200. package/docs/configuration.md +25 -12
  201. package/docs/cost-reporting.md +49 -0
  202. package/docs/historical-data-reconciliation.md +203 -0
  203. package/docs/ingest-journal.md +108 -0
  204. package/docs/ingestion.md +61 -5
  205. package/docs/mcp.md +5 -3
  206. package/docs/native-budget-save.md +84 -0
  207. package/docs/native-human-auth.md +102 -0
  208. package/docs/otel.md +8 -2
  209. package/docs/rest-api.md +4 -4
  210. package/package.json +17 -20
  211. package/postinstall.js +52 -1
  212. package/dashboard/README.md +0 -26
  213. package/dist/cli/brains.d.ts +0 -3
  214. package/dist/cli/brains.d.ts.map +0 -1
  215. package/dist/lib/test-hermetic-accounts.d.ts +0 -6
  216. package/dist/lib/test-hermetic-accounts.d.ts.map +0 -1
@@ -0,0 +1,52 @@
1
+ export declare const LEGACY_FAMILIES: readonly ["codex_aggregate", "hermes_aggregate", "cursor_cumulative", "claude_billing_unverified"];
2
+ export type LegacyFamily = typeof LEGACY_FAMILIES[number];
3
+ export interface LegacyInventoryOptions {
4
+ family?: LegacyFamily;
5
+ limit: number;
6
+ after?: string;
7
+ }
8
+ interface Reader {
9
+ query(sql: string, values?: unknown[]): Promise<{
10
+ rows: Record<string, any>[];
11
+ }>;
12
+ }
13
+ export declare const LEGACY_PREDICATES: Readonly<Record<LegacyFamily, string>>;
14
+ export declare function parseLegacyInventoryOptions(args: string[]): LegacyInventoryOptions;
15
+ /** A bounded, read-only PostgreSQL page. Caller owns and releases the connection.
16
+ * Each call has its own repeatable-read snapshot; pages are NOT one frozen export.
17
+ * An apply operation must independently recheck the exact original row digests.
18
+ */
19
+ export declare function readLegacyInventory(client: Reader, options: LegacyInventoryOptions): Promise<{
20
+ schema: string;
21
+ mode: string;
22
+ original_encoding: string;
23
+ snapshot: {
24
+ at: any;
25
+ database: any;
26
+ scope: string;
27
+ };
28
+ total_requests: number;
29
+ candidate_counts: {
30
+ [k: string]: number;
31
+ };
32
+ filter: string;
33
+ items: {
34
+ id: string;
35
+ session_id: any;
36
+ agent: any;
37
+ family: LegacyFamily;
38
+ original_sha256: string;
39
+ cost_basis: any;
40
+ source_request_id: any;
41
+ timestamp: any;
42
+ updated_at: any;
43
+ disposition: "requires_source_and_preservation_review";
44
+ }[];
45
+ has_more: boolean;
46
+ next_after: string | null;
47
+ mutations_performed: number;
48
+ limitations: string[];
49
+ }>;
50
+ export declare function runLegacyInventory(args: string[]): Promise<void>;
51
+ export {};
52
+ //# sourceMappingURL=legacy-inventory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"legacy-inventory.d.ts","sourceRoot":"","sources":["../../src/server/legacy-inventory.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,eAAe,oGAAqG,CAAA;AACjI,MAAM,MAAM,YAAY,GAAG,OAAO,eAAe,CAAC,MAAM,CAAC,CAAA;AACzD,MAAM,WAAW,sBAAsB;IAAG,MAAM,CAAC,EAAE,YAAY,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE;AAChG,UAAU,MAAM;IAAG,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,CAAA;KAAE,CAAC,CAAA;CAAE;AAIrG,eAAO,MAAM,iBAAiB,EAAE,QAAQ,CAAC,MAAM,CAAC,YAAY,EAAE,MAAM,CAAC,CAKpE,CAAA;AAID,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,sBAAsB,CAqBlF;AAQD;;;GAGG;AACH,wBAAsB,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,sBAAsB;;;;;;;;;;;;;;;;;;gBAqC/D,YAAY;;;;;;;;;;;;GAuBrC;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAWtE"}
@@ -0,0 +1,64 @@
1
+ import type pg from 'pg';
2
+ import type { LegacyReader } from './legacy-plan.js';
3
+ type Action = 'apply' | 'rollback';
4
+ export interface LegacyIntent {
5
+ schema: string;
6
+ operation_key: string;
7
+ target_sha256: string;
8
+ plan_sha256: string;
9
+ capsule_sha256: string;
10
+ actor_ref: string;
11
+ authority_ref: string;
12
+ apply_key?: string;
13
+ }
14
+ /** Only locally authored validation messages may be rendered by the CLI. */
15
+ export declare class LegacyOperationInputError extends Error {
16
+ }
17
+ export declare function parseLegacyIntent(action: Action, value: unknown): LegacyIntent;
18
+ /** Bind the configured connection target without exposing its credential. This
19
+ * complements exact database/relation locators; it is not ownership approval. */
20
+ export declare function legacyTargetDigest(target: string | pg.PoolConfig): string;
21
+ interface Receipt {
22
+ schema: 'economy.legacy-operation-receipt.v1';
23
+ action: Action;
24
+ operation_key: string;
25
+ apply_key: string;
26
+ plan_sha256: string;
27
+ capsule_sha256: string;
28
+ target_requests: number;
29
+ preserved_requests: number;
30
+ sessions: number;
31
+ source_rows_changed: 0;
32
+ created_at: string;
33
+ }
34
+ export declare function applyLegacyReconciliation(client: LegacyReader, input: unknown, preserved: unknown, target: string): Promise<{
35
+ status: "committed";
36
+ receipt: Receipt;
37
+ active: boolean;
38
+ replayed: boolean;
39
+ }>;
40
+ export declare function rollbackLegacyReconciliation(client: LegacyReader, input: unknown, target: string): Promise<{
41
+ status: "committed";
42
+ receipt: Receipt;
43
+ active: boolean;
44
+ replayed: boolean;
45
+ }>;
46
+ /** An absent observation is not proof that an in-flight uncertain command cannot commit. */
47
+ export declare function readLegacyOperation(client: LegacyReader, operation: string): Promise<{
48
+ status: "committed";
49
+ receipt: Receipt;
50
+ active: boolean;
51
+ replayed: boolean;
52
+ } | {
53
+ status: "absent";
54
+ operation_key: string;
55
+ limitation: string;
56
+ }>;
57
+ export declare function parseLegacyOperationOptions(command: string, args: string[]): {
58
+ input?: string;
59
+ capsule?: string;
60
+ operation?: string;
61
+ };
62
+ export declare function runLegacyOperation(command: string, options: ReturnType<typeof parseLegacyOperationOptions>): Promise<void>;
63
+ export {};
64
+ //# sourceMappingURL=legacy-operations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"legacy-operations.d.ts","sourceRoot":"","sources":["../../src/server/legacy-operations.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAA;AAGxB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAQpD,KAAK,MAAM,GAAC,OAAO,GAAC,UAAU,CAAA;AAC9B,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAC,MAAM,CAAC;IAAC,aAAa,EAAC,MAAM,CAAC;IAAC,aAAa,EAAC,MAAM,CAAC;IAAC,WAAW,EAAC,MAAM,CAAC;IAAC,cAAc,EAAC,MAAM,CAAA;IACpG,SAAS,EAAC,MAAM,CAAC;IAAC,aAAa,EAAC,MAAM,CAAC;IAAC,SAAS,CAAC,EAAC,MAAM,CAAA;CAC1D;AACD,4EAA4E;AAC5E,qBAAa,yBAA0B,SAAQ,KAAK;CAAG;AACvD,wBAAgB,iBAAiB,CAAC,MAAM,EAAC,MAAM,EAAC,KAAK,EAAC,OAAO,GAAE,YAAY,CAY1E;AACD;iFACiF;AACjF,wBAAgB,kBAAkB,CAAC,MAAM,EAAC,MAAM,GAAC,EAAE,CAAC,UAAU,GAAE,MAAM,CAOrE;AAgED,UAAU,OAAO;IACf,MAAM,EAAC,qCAAqC,CAAC;IAAA,MAAM,EAAC,MAAM,CAAC;IAAA,aAAa,EAAC,MAAM,CAAC;IAAA,SAAS,EAAC,MAAM,CAAA;IAChG,WAAW,EAAC,MAAM,CAAC;IAAA,cAAc,EAAC,MAAM,CAAC;IAAA,eAAe,EAAC,MAAM,CAAC;IAAA,kBAAkB,EAAC,MAAM,CAAC;IAAA,QAAQ,EAAC,MAAM,CAAA;IACzG,mBAAmB,EAAC,CAAC,CAAC;IAAA,UAAU,EAAC,MAAM,CAAA;CACxC;AAmCD,wBAAsB,yBAAyB,CAAC,MAAM,EAAC,YAAY,EAAC,KAAK,EAAC,OAAO,EAAC,SAAS,EAAC,OAAO,EAAC,MAAM,EAAC,MAAM;;;;;GA8BhH;AACD,wBAAsB,4BAA4B,CAAC,MAAM,EAAC,YAAY,EAAC,KAAK,EAAC,OAAO,EAAC,MAAM,EAAC,MAAM;;;;;GAuBjG;AACD,4FAA4F;AAC5F,wBAAsB,mBAAmB,CAAC,MAAM,EAAC,YAAY,EAAC,SAAS,EAAC,MAAM;;;;;;;;;GAQ7E;AACD,wBAAgB,2BAA2B,CAAC,OAAO,EAAC,MAAM,EAAC,IAAI,EAAC,MAAM,EAAE,GAAE;IAAC,KAAK,CAAC,EAAC,MAAM,CAAC;IAAA,OAAO,CAAC,EAAC,MAAM,CAAC;IAAA,SAAS,CAAC,EAAC,MAAM,CAAA;CAAC,CAQ1H;AACD,wBAAsB,kBAAkB,CAAC,OAAO,EAAC,MAAM,EAAC,OAAO,EAAC,UAAU,CAAC,OAAO,2BAA2B,CAAC,iBAgC7G"}
@@ -0,0 +1,55 @@
1
+ import { type LegacyFamily } from './legacy-inventory.js';
2
+ export interface LegacyReader {
3
+ query(sql: string, values?: unknown[]): Promise<{
4
+ rows: Record<string, any>[];
5
+ }>;
6
+ }
7
+ export interface LegacyPlan {
8
+ schema: string;
9
+ mode: string;
10
+ original_encoding: string;
11
+ member_encoding: string;
12
+ snapshot: {
13
+ at: string;
14
+ database: string;
15
+ database_oid: string;
16
+ tables: Array<Record<string, any>>;
17
+ };
18
+ items: Array<LegacySelection['items'][number] & {
19
+ session_id: string;
20
+ }>;
21
+ sessions: Array<{
22
+ id: string;
23
+ original_sha256: string;
24
+ request_count: number;
25
+ members_sha256: string;
26
+ }>;
27
+ mutations_performed: number;
28
+ limitations: string[];
29
+ plan_sha256: string;
30
+ }
31
+ type Disposition = 'quarantine_aggregate' | 'mark_billing_unknown';
32
+ export interface LegacySelection {
33
+ schema: 'economy.legacy-selection.v1';
34
+ items: Array<{
35
+ id: string;
36
+ family: LegacyFamily;
37
+ original_sha256: string;
38
+ disposition: Disposition;
39
+ reason: string;
40
+ evidence_ref: string;
41
+ }>;
42
+ }
43
+ /** Explicit operator proposals; a source-shape match never chooses a disposition. */
44
+ export declare function parseLegacySelection(value: unknown): LegacySelection;
45
+ /** Open first with nonblocking/no-follow flags, then validate the actual descriptor. */
46
+ export declare function readLegacySelectionFile(path: string): LegacySelection;
47
+ export declare function parseLegacyPlanOptions(args: string[]): string;
48
+ /** One snapshot binds selected requests, their sessions and each session's entire
49
+ * request population. This is a review proposal, not a backup or apply receipt. */
50
+ export declare function prepareLegacyPlan(client: LegacyReader, input: unknown): Promise<LegacyPlan>;
51
+ /** Additional bounded reads share the planner's locked, read-only snapshot. */
52
+ export declare function withLegacyPlanSnapshot<T>(client: LegacyReader, input: unknown, read: (plan: LegacyPlan) => Promise<T>): Promise<T>;
53
+ export declare function runLegacyPlan(selection: LegacySelection): Promise<void>;
54
+ export {};
55
+ //# sourceMappingURL=legacy-plan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"legacy-plan.d.ts","sourceRoot":"","sources":["../../src/server/legacy-plan.ts"],"names":[],"mappings":"AAGA,OAAO,EAAsC,KAAK,YAAY,EAAE,MAAM,uBAAuB,CAAA;AAE7F,MAAM,WAAW,YAAY;IAAG,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,CAAA;KAAE,CAAC,CAAA;CAAE;AAClH,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,iBAAiB,EAAE,MAAM,CAAC;IAAC,eAAe,EAAE,MAAM,CAAA;IAChF,QAAQ,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAA;KAAE,CAAA;IACpG,KAAK,EAAE,KAAK,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,GAAG;QAAE,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IACvE,QAAQ,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,eAAe,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAC;QAAC,cAAc,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IACvG,mBAAmB,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,EAAE,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CACxE;AACD,KAAK,WAAW,GAAG,sBAAsB,GAAG,sBAAsB,CAAA;AAClE,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,6BAA6B,CAAA;IACrC,KAAK,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,YAAY,CAAC;QAAC,eAAe,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,WAAW,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAC5I;AAuBD,qFAAqF;AACrF,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,eAAe,CAkBpE;AAED,wFAAwF;AACxF,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,CAkBrE;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CAG7D;AAED;mFACmF;AACnF,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC,CAEjG;AAED,+EAA+E;AAC/E,wBAAsB,sBAAsB,CAAC,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,OAAO,EAClF,IAAI,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAwEpD;AAED,wBAAsB,aAAa,CAAC,SAAS,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAU7E"}
@@ -0,0 +1,58 @@
1
+ import { type LegacyPlan, type LegacyReader } from './legacy-plan.js';
2
+ /** Validate the complete emitted proposal before taking a connection or opening output. */
3
+ export declare function parseLegacyPlan(value: unknown): LegacyPlan;
4
+ export declare function assertLegacyPlanCurrent(expected: LegacyPlan, current: LegacyPlan): void;
5
+ interface Original {
6
+ id: string;
7
+ original: string;
8
+ }
9
+ export interface LegacyCapsule {
10
+ schema: 'economy.legacy-preservation.v1';
11
+ plan: LegacyPlan;
12
+ captured_at: string;
13
+ requests: Original[];
14
+ sessions: Original[];
15
+ capsule_sha256: string;
16
+ }
17
+ /** Full original JSON remains text: JS never round-trips PostgreSQL integers/floats. */
18
+ export declare function parseLegacyCapsule(value: unknown): LegacyCapsule;
19
+ export declare function preserveLegacyOriginals(client: LegacyReader, input: unknown): Promise<LegacyCapsule>;
20
+ export declare function readLegacyArtifact(path: string, maxBytes?: number): unknown;
21
+ /** Never overwrite a previous capture. On interruption the partial file is retained
22
+ * and must be inspected; retry uses a new destination after checking the original. */
23
+ export declare function writeLegacyCapsule(path: string, input: unknown): {
24
+ schema: string;
25
+ file: string;
26
+ plan_sha256: string;
27
+ capsule_sha256: string;
28
+ file_sha256: string;
29
+ requests: number;
30
+ sessions: number;
31
+ readback: string;
32
+ restore: string;
33
+ source_mutations: number;
34
+ };
35
+ /** Reconstruct native typed rows in transaction-local TEMP tables, compare the
36
+ * original PostgreSQL JSON bytes, then ROLLBACK. No application row is written.
37
+ * This is a logical selected-row restore rehearsal, not a whole-store restore. */
38
+ export declare function rehearseLegacyRestore(client: LegacyReader, input: unknown, scope?: 'transaction' | 'savepoint'): Promise<{
39
+ schema: string;
40
+ capsule_sha256: string;
41
+ plan_sha256: string;
42
+ requests: number;
43
+ sessions: number;
44
+ restored_original_bytes: string;
45
+ temporary_rows: string;
46
+ source_mutations: number;
47
+ scope: string;
48
+ }>;
49
+ export declare function parseLegacyPreservationOptions(command: string, args: string[]): {
50
+ input: string;
51
+ output?: string;
52
+ };
53
+ export declare function runLegacyPreservation(command: string, options: {
54
+ input: string;
55
+ output?: string;
56
+ }): Promise<void>;
57
+ export {};
58
+ //# sourceMappingURL=legacy-preservation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"legacy-preservation.d.ts","sourceRoot":"","sources":["../../src/server/legacy-preservation.ts"],"names":[],"mappings":"AAGA,OAAO,EAAgD,KAAK,UAAU,EAAE,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAgBnH,2FAA2F;AAC3F,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,UAAU,CA6C1D;AAOD,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU,GAAG,IAAI,CAEvF;AAED,UAAU,QAAQ;IAAG,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE;AACnD,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,gCAAgC,CAAA;IACxC,IAAI,EAAE,UAAU,CAAA;IAChB,WAAW,EAAE,MAAM,CAAA;IACnB,QAAQ,EAAE,QAAQ,EAAE,CAAA;IACpB,QAAQ,EAAE,QAAQ,EAAE,CAAA;IACpB,cAAc,EAAE,MAAM,CAAA;CACvB;AAED,wFAAwF;AACxF,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,aAAa,CAmChE;AAED,wBAAsB,uBAAuB,CAAC,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,aAAa,CAAC,CAiB1G;AAmBD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,SAAU,GAAG,OAAO,CAI5E;AAED;sFACsF;AACtF,wBAAgB,kBAAkB,CAAC,IAAI,EAAC,MAAM,EAAC,KAAK,EAAC,OAAO;;;;;;;;;;;EAwB3D;AAED;;kFAEkF;AAClF,wBAAsB,qBAAqB,CAAC,MAAM,EAAC,YAAY,EAAC,KAAK,EAAC,OAAO,EAAC,KAAK,GAAC,aAAa,GAAC,WAAyB;;;;;;;;;;GAwD1H;AAED,wBAAgB,8BAA8B,CAAC,OAAO,EAAC,MAAM,EAAC,IAAI,EAAC,MAAM,EAAE,GAAG;IAAC,KAAK,EAAC,MAAM,CAAC;IAAA,MAAM,CAAC,EAAC,MAAM,CAAA;CAAC,CAM1G;AAED,wBAAsB,qBAAqB,CAAC,OAAO,EAAC,MAAM,EAAC,OAAO,EAAC;IAAC,KAAK,EAAC,MAAM,CAAC;IAAA,MAAM,CAAC,EAAC,MAAM,CAAA;CAAC,iBAgB/F"}
@@ -1,31 +1,205 @@
1
1
  // @bun
2
2
  // src/db/pg-sync-worker.ts
3
3
  import { parentPort, workerData } from "worker_threads";
4
+ import pg2 from "pg";
5
+
6
+ // src/db/pg-connection.ts
4
7
  import pg from "pg";
5
- pg.types.setTypeParser(20, (v) => v === null ? null : Number(v));
6
- pg.types.setTypeParser(1700, (v) => v === null ? null : Number(v));
7
- var dsn = workerData?.dsn;
8
- var ssl = dsn && (dsn.includes("sslmode=require") || dsn.includes("ssl=true")) ? { rejectUnauthorized: false } : undefined;
9
- var pool = new pg.Pool({
10
- connectionString: dsn,
11
- ssl,
12
- max: Number(process.env["ECONOMY_PG_POOL_MAX"] ?? "5"),
13
- connectionTimeoutMillis: 1e4
14
- });
15
- pool.on("error", (err) => {
16
- console.error(JSON.stringify({ evt: "pg_worker_pool_error", message: err.message }));
17
- });
18
- var replyPort = null;
8
+ import { checkServerIdentity } from "tls";
9
+ function resolvePgConnection(dsn) {
10
+ try {
11
+ const client = new pg.Client({ connectionString: dsn });
12
+ const resolved = client.connectionParameters;
13
+ const ssl = resolved.ssl;
14
+ const host = resolved.host.replace(/^\[|\]$/g, "");
15
+ const tls = ssl ? {
16
+ ...typeof ssl === "object" ? ssl : {},
17
+ rejectUnauthorized: true,
18
+ checkServerIdentity: (_servername, cert) => checkServerIdentity(host, cert)
19
+ } : false;
20
+ return { ...resolved, password: resolved.password, ssl: tls };
21
+ } catch {
22
+ throw new Error("PostgreSQL connection configuration is invalid or its TLS files are unreadable");
23
+ }
24
+ }
25
+
26
+ // src/db/pg-protocol.ts
27
+ function pgNow() {
28
+ return performance.timeOrigin + performance.now();
29
+ }
30
+
31
+ // src/db/pg-sync-worker.ts
32
+ pg2.types.setTypeParser(20, (v) => v === null ? null : Number(v));
33
+ pg2.types.setTypeParser(1700, (v) => v === null ? null : Number(v));
34
+ var config = workerData;
35
+ var lifecycle = new Int32Array(config.lifecycle);
36
+ var pool;
37
+ try {
38
+ pool = new pg2.Pool({
39
+ ...resolvePgConnection(config.dsn),
40
+ max: Number(process.env["ECONOMY_PG_POOL_MAX"] ?? "5"),
41
+ connectionTimeoutMillis: Math.min(config.queryTimeoutMs, 1e4),
42
+ statement_timeout: config.queryTimeoutMs,
43
+ idle_in_transaction_session_timeout: config.transactionTimeoutMs
44
+ });
45
+ pool.on("error", () => {});
46
+ } catch {}
47
+ var replyPort;
48
+ var leased;
49
+ var transactionId = null;
50
+ var queue = Promise.resolve();
51
+ function onIdleTransactionError() {
52
+ Atomics.store(lifecycle, 0, 1);
53
+ const client = leased;
54
+ leased = undefined;
55
+ transactionId = null;
56
+ client?.release(true);
57
+ }
58
+ function fail(code) {
59
+ return Object.assign(new Error(code), { code });
60
+ }
61
+ async function execute(msg) {
62
+ let active;
63
+ let done = false;
64
+ let destroyed = false;
65
+ let releaseTransaction = false;
66
+ const finish = (reply) => {
67
+ if (done)
68
+ return;
69
+ done = true;
70
+ replyPort?.postMessage(reply);
71
+ const signal = new Int32Array(msg.signal);
72
+ Atomics.store(signal, 0, 1);
73
+ Atomics.notify(signal, 0);
74
+ };
75
+ const destroy = () => {
76
+ if (destroyed)
77
+ return;
78
+ destroyed = true;
79
+ Atomics.store(lifecycle, 0, 1);
80
+ const client = active ?? leased;
81
+ leased = undefined;
82
+ transactionId = null;
83
+ client?.release(true);
84
+ };
85
+ const check = () => {
86
+ if (done || pgNow() >= msg.deadline || Atomics.load(lifecycle, 0) !== 0)
87
+ throw fail("ECONOMY_PG_ABANDONED");
88
+ };
89
+ const timer = setTimeout(() => {
90
+ destroy();
91
+ finish({
92
+ id: msg.id,
93
+ ok: false,
94
+ code: "ECONOMY_PG_TIMEOUT",
95
+ fatal: true,
96
+ error: "PostgreSQL operation deadline exceeded; write outcome may be unknown"
97
+ });
98
+ }, Math.max(1, msg.deadline - pgNow()));
99
+ const onClientError = () => {
100
+ destroy();
101
+ finish({
102
+ id: msg.id,
103
+ ok: false,
104
+ code: "ECONOMY_PG_CONNECTION",
105
+ fatal: true,
106
+ error: "PostgreSQL connection failed; write outcome may be unknown"
107
+ });
108
+ };
109
+ try {
110
+ check();
111
+ if (!pool)
112
+ throw fail("ECONOMY_PG_CONFIG");
113
+ if (msg.operation === "begin" ? transactionId !== null : msg.transactionId !== transactionId) {
114
+ throw fail("ECONOMY_PG_TRANSACTION");
115
+ }
116
+ active = leased ?? await pool.connect();
117
+ if (destroyed || done) {
118
+ active.release(true);
119
+ active = undefined;
120
+ return;
121
+ }
122
+ active.removeListener("error", onIdleTransactionError);
123
+ active.on("error", onClientError);
124
+ check();
125
+ let sql;
126
+ const savepoint = `economy_sp_${msg.depth}`;
127
+ switch (msg.operation) {
128
+ case "begin":
129
+ sql = "BEGIN";
130
+ break;
131
+ case "commit":
132
+ sql = "COMMIT";
133
+ break;
134
+ case "rollback":
135
+ sql = "ROLLBACK";
136
+ break;
137
+ case "savepoint":
138
+ sql = `SAVEPOINT ${savepoint}`;
139
+ break;
140
+ case "release":
141
+ sql = `RELEASE SAVEPOINT ${savepoint}`;
142
+ break;
143
+ case "rollbackTo":
144
+ sql = `ROLLBACK TO SAVEPOINT ${savepoint}`;
145
+ break;
146
+ case "query":
147
+ sql = msg.sql;
148
+ break;
149
+ default:
150
+ throw fail("ECONOMY_PG_PROTOCOL");
151
+ }
152
+ const result = await active.query(sql, msg.operation === "query" ? msg.params : []);
153
+ check();
154
+ if (msg.operation === "begin") {
155
+ leased = active;
156
+ transactionId = msg.transactionId;
157
+ }
158
+ if (msg.operation === "rollbackTo") {
159
+ check();
160
+ await active.query(`RELEASE SAVEPOINT ${savepoint}`);
161
+ check();
162
+ }
163
+ const last = Array.isArray(result) ? result.at(-1) : result;
164
+ if (msg.operation === "commit" && last?.command !== "COMMIT")
165
+ throw fail("25P02");
166
+ releaseTransaction = msg.operation === "commit" || msg.operation === "rollback";
167
+ finish({ id: msg.id, ok: true, rows: last?.rows ?? [], rowCount: last?.rowCount ?? 0 });
168
+ } catch (error) {
169
+ const rawCode = error?.code;
170
+ const sqlState = typeof rawCode === "string" && /^[0-9A-Z]{5}$/.test(rawCode) ? rawCode : undefined;
171
+ const fatal = !sqlState || sqlState.startsWith("08") || /^57P0[123]$/.test(sqlState);
172
+ if (fatal)
173
+ destroy();
174
+ const code = sqlState ?? "ECONOMY_PG_UNAVAILABLE";
175
+ finish({
176
+ id: msg.id,
177
+ ok: false,
178
+ code,
179
+ fatal,
180
+ error: sqlState ? `PostgreSQL operation failed (${sqlState})` : "PostgreSQL connection or worker unavailable; write outcome may be unknown"
181
+ });
182
+ } finally {
183
+ clearTimeout(timer);
184
+ active?.removeListener("error", onClientError);
185
+ if (!destroyed && active) {
186
+ if (releaseTransaction) {
187
+ leased = undefined;
188
+ transactionId = null;
189
+ }
190
+ if (active !== leased)
191
+ active.release();
192
+ else
193
+ active.on("error", onIdleTransactionError);
194
+ }
195
+ }
196
+ }
19
197
  parentPort?.on("message", (msg) => {
20
- if (msg.type === "init") {
198
+ if ("type" in msg) {
21
199
  replyPort = msg.port;
22
200
  return;
23
201
  }
24
- const { id, sql, params, signal } = msg;
25
- const sig = new Int32Array(signal);
26
- pool.query(sql, params).then((res) => ({ id, ok: true, rows: res.rows, rowCount: res.rowCount ?? 0 })).catch((err) => ({ id, ok: false, error: err instanceof Error ? err.message : String(err) })).then((response) => {
27
- replyPort?.postMessage(response);
28
- Atomics.store(sig, 0, 1);
29
- Atomics.notify(sig, 0);
202
+ queue = queue.then(() => execute(msg)).catch(() => {
203
+ Atomics.store(lifecycle, 0, 1);
30
204
  });
31
205
  });
@@ -1,11 +1,7 @@
1
1
  import type { SqliteAdapter as Database } from '../db/sqlite-adapter.js';
2
- /** The serve OpenAPI document (source of the generated SDK), version-synced. */
2
+ import { type ServiceLimits } from './service-dispatcher.js';
3
+ import { type OperationDispatcher } from './service-protocol.js';
3
4
  export declare function openApiDocument(): Record<string, unknown>;
4
- /**
5
- * Framework-agnostic API-key verifier shape (matches `@hasna/contracts/auth`
6
- * `ApiKeyVerifier`). Kept structural so serve.ts has no hard dependency on the
7
- * auth package; the entry point injects the real verifier.
8
- */
9
5
  export interface ApiAuthenticator {
10
6
  authenticate(headers: Headers, context?: {
11
7
  method?: string | null;
@@ -16,27 +12,33 @@ export interface ApiAuthenticator {
16
12
  status: number;
17
13
  reason?: string;
18
14
  message?: string;
15
+ principal?: {
16
+ tid: string | null;
17
+ kid: string;
18
+ kind?: 'human';
19
+ subject?: string;
20
+ scopes?: string[];
21
+ sessionId?: string;
22
+ expiresAt?: number;
23
+ };
19
24
  }>;
20
25
  }
21
- interface StartServerOptions {
22
- db?: Database;
23
- dashboardDir?: string;
24
- hostname?: string;
25
- log?: (message: string) => void;
26
- }
27
- export declare function createServerFetch(apiHandler: (req: Request) => Promise<Response>, dashboardDir?: string): (req: Request) => Promise<Response>;
28
26
  export interface HandlerOptions {
29
- /** API-key verifier (from `@hasna/contracts/auth`). When present, every
30
- * request outside the open foundation probes must present a valid
31
- * `economy:*` scoped key. This is the internet-facing auth path. */
32
27
  authenticator?: ApiAuthenticator;
33
- /** Readiness probe proving storage is reachable + migrated. */
34
28
  readyCheck?: () => Promise<{
35
29
  ready: boolean;
36
30
  detail?: string;
37
31
  }>;
32
+ limits?: ServiceLimits;
33
+ }
34
+ interface StartServerOptions {
35
+ db?: Database;
36
+ hostname?: string;
37
+ log?: (message: string) => void;
38
38
  }
39
- export declare function createHandler(db: Database, options?: HandlerOptions): (req: Request) => Promise<Response>;
39
+ /** Explicit injected database handles remain supported for embedding/tests.
40
+ * The production server always supplies an asynchronous operation dispatcher. */
41
+ export declare function createHandler(target: Database | OperationDispatcher, options?: HandlerOptions): (req: Request) => Promise<Response>;
40
42
  export declare function startServer(port?: number, options?: StartServerOptions): ReturnType<typeof Bun.serve>;
41
43
  export {};
42
44
  //# sourceMappingURL=serve.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["../../src/server/serve.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,IAAI,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AAgDxE,gFAAgF;AAChF,wBAAgB,eAAe,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAGzD;AAED;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B,YAAY,CACV,OAAO,EAAE,OAAO,EAChB,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;KAAE,GAC7F,OAAO,CAAC;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAC/E;AAuBD,UAAU,kBAAkB;IAC1B,EAAE,CAAC,EAAE,QAAQ,CAAA;IACb,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;CAChC;AA6ED,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,EAAE,YAAY,SAAwB,IACzF,KAAK,OAAO,KAAG,OAAO,CAAC,QAAQ,CAAC,CAwB7D;AAQD,MAAM,WAAW,cAAc;IAC7B;;wEAEoE;IACpE,aAAa,CAAC,EAAE,gBAAgB,CAAA;IAChC,+DAA+D;IAC/D,UAAU,CAAC,EAAE,MAAM,OAAO,CAAC;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAChE;AAED,wBAAgB,aAAa,CAAC,EAAE,EAAE,QAAQ,EAAE,OAAO,GAAE,cAAmB,IACxC,KAAK,OAAO,KAAG,OAAO,CAAC,QAAQ,CAAC,CAmhB/D;AAMD,wBAAgB,WAAW,CAAC,IAAI,SAAO,EAAE,OAAO,GAAE,kBAAuB,GAAG,UAAU,CAAC,OAAO,GAAG,CAAC,KAAK,CAAC,CAqDvG"}
1
+ {"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["../../src/server/serve.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,IAAI,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AAOxE,OAAO,EAA6D,KAAK,aAAa,EAAE,MAAM,yBAAyB,CAAA;AACvH,OAAO,EAAgB,KAAK,mBAAmB,EAAE,MAAM,uBAAuB,CAAA;AAK9E,wBAAgB,eAAe,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAGzD;AACD,MAAM,WAAW,gBAAgB;IAC/B,YAAY,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;KAAE,GAC3H,OAAO,CAAC;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE;YAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;YAAC,GAAG,EAAE,MAAM,CAAC;YAAC,IAAI,CAAC,EAAE,OAAO,CAAC;YAAC,OAAO,CAAC,EAAE,MAAM,CAAC;YAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;YAAC,SAAS,CAAC,EAAE,MAAM,CAAC;YAAC,SAAS,CAAC,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,CAAC,CAAA;CAC5N;AASD,MAAM,WAAW,cAAc;IAC7B,aAAa,CAAC,EAAE,gBAAgB,CAAA;IAChC,UAAU,CAAC,EAAE,MAAM,OAAO,CAAC;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IAC/D,MAAM,CAAC,EAAE,aAAa,CAAA;CACvB;AACD,UAAU,kBAAkB;IAC1B,EAAE,CAAC,EAAE,QAAQ,CAAA;IACb,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;CAChC;AAmCD;iFACiF;AACjF,wBAAgB,aAAa,CAAC,MAAM,EAAE,QAAQ,GAAG,mBAAmB,EAAE,OAAO,GAAE,cAAmB,IAOlE,KAAK,OAAO,KAAG,OAAO,CAAC,QAAQ,CAAC,CA4E/D;AAGD,wBAAgB,WAAW,CAAC,IAAI,SAAO,EAAE,OAAO,GAAE,kBAAuB,GAAG,UAAU,CAAC,OAAO,GAAG,CAAC,KAAK,CAAC,CA+DvG"}
@@ -0,0 +1,10 @@
1
+ /** Bound asynchronous authority/readiness work independently of data workers.
2
+ * A timed-out caller does not free admission until the underlying call settles. */
3
+ export declare class ServiceAdmission {
4
+ private readonly capacity;
5
+ private readonly deadlineMs;
6
+ private active;
7
+ constructor(capacity: number, deadlineMs: number);
8
+ run<T>(work: () => Promise<T>): Promise<T>;
9
+ }
10
+ //# sourceMappingURL=service-admission.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service-admission.d.ts","sourceRoot":"","sources":["../../src/server/service-admission.ts"],"names":[],"mappings":"AAAA;mFACmF;AACnF,qBAAa,gBAAgB;IAEf,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAAU,OAAO,CAAC,QAAQ,CAAC,UAAU;IAD1E,OAAO,CAAC,MAAM,CAAI;gBACW,QAAQ,EAAE,MAAM,EAAmB,UAAU,EAAE,MAAM;IAC5E,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;CAYjD"}
@@ -0,0 +1,45 @@
1
+ import { type OperationDispatcher, type ServiceBackend, type ServiceOperation, type ServiceResult } from './service-protocol.js';
2
+ export interface ServiceLimits {
3
+ workers: number;
4
+ maxQueue: number;
5
+ deadlineMs: number;
6
+ maxInputBytes: number;
7
+ maxResultBytes: number;
8
+ maxQueuedBytes: number;
9
+ }
10
+ export declare const DEFAULT_SERVICE_LIMITS: ServiceLimits;
11
+ export declare function serviceLimits(env?: Record<string, string | undefined>): ServiceLimits;
12
+ export declare class ServiceUnavailable extends Error {
13
+ readonly code: string;
14
+ readonly status: number;
15
+ readonly operationId: string;
16
+ readonly outcome: 'not_started' | 'unknown';
17
+ constructor(code: string, status: number, operationId: string, outcome: 'not_started' | 'unknown');
18
+ }
19
+ /** Bounded operation processes, bounded queued input and one deadline per call.
20
+ * No request is replayed. A new operation gets an independent process/context. */
21
+ export declare class AsyncServiceDispatcher implements OperationDispatcher {
22
+ private readonly backend;
23
+ readonly limits: ServiceLimits;
24
+ private readonly queue;
25
+ private readonly active;
26
+ private generation;
27
+ private queuedBytes;
28
+ private stopped;
29
+ constructor(backend: ServiceBackend, limits?: ServiceLimits);
30
+ dispatch(operation: ServiceOperation, signal?: AbortSignal, beforeStart?: () => Promise<void>): Promise<ServiceResult>;
31
+ private settle;
32
+ private fail;
33
+ private pump;
34
+ private start;
35
+ private launch;
36
+ /** Metadata only; no PID, SQL, bodies or credentials. */
37
+ state(): {
38
+ active: number;
39
+ queued: number;
40
+ queuedBytes: number;
41
+ stopped: boolean;
42
+ };
43
+ close(): Promise<void>;
44
+ }
45
+ //# sourceMappingURL=service-dispatcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service-dispatcher.d.ts","sourceRoot":"","sources":["../../src/server/service-dispatcher.ts"],"names":[],"mappings":"AAIA,OAAO,EAAkB,KAAK,mBAAmB,EAAE,KAAK,cAAc,EAAE,KAAK,gBAAgB,EAAE,KAAK,aAAa,EAAoB,MAAM,uBAAuB,CAAA;AAElK,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,MAAM,CAAA;IAClB,aAAa,EAAE,MAAM,CAAA;IACrB,cAAc,EAAE,MAAM,CAAA;IACtB,cAAc,EAAE,MAAM,CAAA;CACvB;AACD,eAAO,MAAM,sBAAsB,EAAE,aAGpC,CAAA;AACD,wBAAgB,aAAa,CAAC,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAe,GAAG,aAAa,CAelG;AACD,qBAAa,kBAAmB,SAAQ,KAAK;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM;IAAE,QAAQ,CAAC,MAAM,EAAE,MAAM;IAAE,QAAQ,CAAC,WAAW,EAAE,MAAM;IACtF,QAAQ,CAAC,OAAO,EAAE,aAAa,GAAG,SAAS;gBADxB,IAAI,EAAE,MAAM,EAAW,MAAM,EAAE,MAAM,EAAW,WAAW,EAAE,MAAM,EAC7E,OAAO,EAAE,aAAa,GAAG,SAAS;CAC9C;AAiBD;kFACkF;AAClF,qBAAa,sBAAuB,YAAW,mBAAmB;IAMpD,OAAO,CAAC,QAAQ,CAAC,OAAO;IAAkB,QAAQ,CAAC,MAAM;IALrE,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAY;IAClC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiB;IACxC,OAAO,CAAC,UAAU,CAAI;IACtB,OAAO,CAAC,WAAW,CAAI;IACvB,OAAO,CAAC,OAAO,CAAQ;gBACM,OAAO,EAAE,cAAc,EAAW,MAAM,gBAAkB;IAEvF,QAAQ,CAAC,SAAS,EAAE,gBAAgB,EAAE,MAAM,CAAC,EAAE,WAAW,EAAE,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,aAAa,CAAC;IA0BtH,OAAO,CAAC,MAAM;IASd,OAAO,CAAC,IAAI;IAQZ,OAAO,CAAC,IAAI;IASZ,OAAO,CAAC,KAAK;IAiBb,OAAO,CAAC,MAAM;IA8Cd,yDAAyD;IACzD,KAAK,IAAI;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE;IAG5E,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAS7B"}
@@ -0,0 +1,5 @@
1
+ import type { SqliteAdapter as Database } from '../db/sqlite-adapter.js';
2
+ import type { ServiceOperation, ServiceResult } from './service-protocol.js';
3
+ /** Execute one complete, already-authorized operation. No request authorization headers enter this executor. */
4
+ export declare function executeServiceOperation(db: Database, operation: ServiceOperation): Promise<ServiceResult>;
5
+ //# sourceMappingURL=service-operations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service-operations.d.ts","sourceRoot":"","sources":["../../src/server/service-operations.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,IAAI,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AAuCxE,OAAO,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAA;AA6jB5E,gHAAgH;AAChH,wBAAsB,uBAAuB,CAAC,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,gBAAgB,GAAG,OAAO,CAAC,aAAa,CAAC,CAe/G"}