@mongrov/analytics 0.3.0 → 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 (60) hide show
  1. package/dist/core/errors.js +1 -1
  2. package/dist/core/errors.js.map +1 -1
  3. package/dist/core/extensions.d.ts +20 -6
  4. package/dist/core/extensions.d.ts.map +1 -1
  5. package/dist/core/extensions.js +21 -7
  6. package/dist/core/extensions.js.map +1 -1
  7. package/dist/core/factory.d.ts.map +1 -1
  8. package/dist/core/factory.js +90 -15
  9. package/dist/core/factory.js.map +1 -1
  10. package/dist/core/migrations.d.ts +22 -4
  11. package/dist/core/migrations.d.ts.map +1 -1
  12. package/dist/core/migrations.js +46 -7
  13. package/dist/core/migrations.js.map +1 -1
  14. package/dist/core/schemas.d.ts +36 -5
  15. package/dist/core/schemas.d.ts.map +1 -1
  16. package/dist/core/schemas.js +39 -6
  17. package/dist/core/schemas.js.map +1 -1
  18. package/dist/core/types.d.ts +43 -5
  19. package/dist/core/types.d.ts.map +1 -1
  20. package/dist/core/warehouse.d.ts +55 -5
  21. package/dist/core/warehouse.d.ts.map +1 -1
  22. package/dist/core/warehouse.js +93 -18
  23. package/dist/core/warehouse.js.map +1 -1
  24. package/dist/rules/__fakes__/fakeEngine.d.ts +3 -1
  25. package/dist/rules/__fakes__/fakeEngine.d.ts.map +1 -1
  26. package/dist/rules/__fakes__/fakeEngine.js +4 -1
  27. package/dist/rules/__fakes__/fakeEngine.js.map +1 -1
  28. package/dist/rules/defaults/loader.d.ts.map +1 -1
  29. package/dist/rules/defaults/loader.js +4 -2
  30. package/dist/rules/defaults/loader.js.map +1 -1
  31. package/dist/rules/emitter.d.ts +2 -0
  32. package/dist/rules/emitter.d.ts.map +1 -1
  33. package/dist/rules/emitter.js +3 -0
  34. package/dist/rules/emitter.js.map +1 -1
  35. package/dist/rules/evaluator.d.ts.map +1 -1
  36. package/dist/rules/evaluator.js +4 -0
  37. package/dist/rules/evaluator.js.map +1 -1
  38. package/dist/rules/factory.d.ts.map +1 -1
  39. package/dist/rules/factory.js +29 -4
  40. package/dist/rules/factory.js.map +1 -1
  41. package/dist/rules/registry.d.ts +8 -0
  42. package/dist/rules/registry.d.ts.map +1 -1
  43. package/dist/rules/registry.js +22 -0
  44. package/dist/rules/registry.js.map +1 -1
  45. package/dist/rules/types.d.ts +9 -0
  46. package/dist/rules/types.d.ts.map +1 -1
  47. package/dist/sync/factory.d.ts.map +1 -1
  48. package/dist/sync/factory.js +20 -7
  49. package/dist/sync/factory.js.map +1 -1
  50. package/dist/sync/fetcher.d.ts.map +1 -1
  51. package/dist/sync/fetcher.js +2 -1
  52. package/dist/sync/fetcher.js.map +1 -1
  53. package/dist/sync/pusher.d.ts +10 -3
  54. package/dist/sync/pusher.d.ts.map +1 -1
  55. package/dist/sync/pusher.js +1 -1
  56. package/dist/sync/pusher.js.map +1 -1
  57. package/dist/tools/__fakes__/engine.d.ts.map +1 -1
  58. package/dist/tools/__fakes__/engine.js +1 -0
  59. package/dist/tools/__fakes__/engine.js.map +1 -1
  60. package/package.json +3 -3
@@ -5,10 +5,21 @@
5
5
  * DDL strings are frozen — apps must not mutate them; migrations (T-08) own
6
6
  * schema evolution.
7
7
  *
8
- * `ensureSchemas(db, catalog)` idempotently creates every table inside the
9
- * attached catalog (i.e. `zone_<tenantId>`), rewriting `CREATE TABLE <name>`
10
- * to `CREATE TABLE IF NOT EXISTS <catalog>.<name>` at issue time so the base
11
- * DDL stays faithful to the spec text.
8
+ * Two DDL variants exist:
9
+ * - `SCHEMAS` for Iceberg-attached remote catalogs. Includes
10
+ * `PARTITIONED BY (day(ts), user_id)` clauses that Iceberg requires
11
+ * for partition pruning at scan time.
12
+ * - `LOCAL_SCHEMAS` — for the app's local DuckDB catalog. Identical to
13
+ * `SCHEMAS` minus the `PARTITIONED BY` clauses, which plain DuckDB
14
+ * (non-Iceberg) rejects with a parser error. Derived from `SCHEMAS`
15
+ * via `toLocalDdl` at module load time so both variants stay in sync
16
+ * through schema changes.
17
+ *
18
+ * `ensureSchemas(db, catalog, schemas)` idempotently creates every table
19
+ * inside the given catalog, rewriting `CREATE TABLE <name>` to
20
+ * `CREATE TABLE IF NOT EXISTS <catalog>.<name>` at issue time. Callers
21
+ * pick the variant: remote attach uses `SCHEMAS`, local mode uses
22
+ * `LOCAL_SCHEMAS`.
12
23
  */
13
24
  import { AnalyticsError } from './errors';
14
25
  /** Ordered list of every warehouse table. Order = creation order. */
@@ -189,15 +200,37 @@ export const SCHEMAS = Object.freeze({
189
200
  export function qualifyDdl(baseDdl, table, catalog) {
190
201
  return baseDdl.replace(`CREATE TABLE ${table}`, `CREATE TABLE IF NOT EXISTS ${catalog}.${table}`);
191
202
  }
203
+ /**
204
+ * Strip the Iceberg-only `PARTITIONED BY (...)` clause from a DDL string.
205
+ * Plain DuckDB (non-Iceberg) rejects the clause with a parser error; local
206
+ * mode uses the returned form. Preserves the trailing `);` terminator.
207
+ *
208
+ * Exported for tests; call sites should prefer `LOCAL_SCHEMAS`.
209
+ */
210
+ export function toLocalDdl(baseDdl) {
211
+ return baseDdl.replace(/\)\s*PARTITIONED BY\s*\([^)]*\);?/g, ');');
212
+ }
213
+ /**
214
+ * Local-catalog DDL variants of `SCHEMAS` — same tables, same columns,
215
+ * same primary keys; only difference is the `PARTITIONED BY` clauses are
216
+ * stripped. Derived programmatically so schema changes in `SCHEMAS`
217
+ * propagate automatically.
218
+ */
219
+ export const LOCAL_SCHEMAS = Object.freeze(Object.fromEntries(TABLE_NAMES.map(table => [table, toLocalDdl(SCHEMAS[table])])));
192
220
  /**
193
221
  * Create every warehouse table under `<catalog>.<table>`, in `TABLE_NAMES` order.
194
222
  *
195
223
  * Idempotent — every issued statement uses `IF NOT EXISTS`. Failure at any
196
224
  * table surfaces as `AnalyticsError('migration_failed', <table>, cause)`.
225
+ *
226
+ * `schemas` selects the DDL variant: pass `SCHEMAS` for remote iceberg
227
+ * catalogs (with `PARTITIONED BY`), `LOCAL_SCHEMAS` for the local DuckDB
228
+ * catalog (without). Default is `SCHEMAS` for back-compat with 0.4.x
229
+ * callers that only wrote to the attached remote.
197
230
  */
198
- export async function ensureSchemas(db, catalog) {
231
+ export async function ensureSchemas(db, catalog, schemas = SCHEMAS) {
199
232
  for (const table of TABLE_NAMES) {
200
- const sql = qualifyDdl(SCHEMAS[table], table, catalog);
233
+ const sql = qualifyDdl(schemas[table], table, catalog);
201
234
  try {
202
235
  await db.execute(sql);
203
236
  }
@@ -1 +1 @@
1
- {"version":3,"file":"schemas.js","sourceRoot":"","sources":["../../src/core/schemas.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAGzC,qEAAqE;AACrE,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,KAAK;IACL,YAAY;IACZ,MAAM;IACN,aAAa;IACb,UAAU;IACV,iBAAiB;IACjB,eAAe;IACf,aAAa;IACb,WAAW;IACX,cAAc;IACd,eAAe;IACf,SAAS;IACT,gBAAgB;IAChB,iBAAiB;CACT,CAAA;AAIV;;;GAGG;AACH,MAAM,CAAC,MAAM,OAAO,GAAwC,MAAM,CAAC,MAAM,CAAC;IACxE,GAAG,EAAE;;;;;;;;;;;qCAW8B;IAEnC,UAAU,EAAE;;;;;;;qCAOuB;IAEnC,IAAI,EAAE;;;;;;;qCAO6B;IAEnC,WAAW,EAAE;;;;;;;qCAOsB;IAEnC,QAAQ,EAAE;;;;;;;qCAOyB;IAEnC,eAAe,EAAE;;;;;;;;qCAQkB;IAEnC,aAAa,EAAE;;;;;;;;;;;;;;;2CAe0B;IAEzC,WAAW,EAAE;;;;;;;;;qCASsB;IAEnC,SAAS,EAAE;;;;;;;;;mDASsC;IAEjD,YAAY,EAAE;;;;;;;;4BAQY;IAE1B,aAAa,EAAE;;;;;;;;;;;;;GAad;IAED,OAAO,EAAE;;;;;;;;;;;;4BAYiB;IAE1B,cAAc,EAAE;;;;;;;;GAQf;IAED,eAAe,EAAE;;;;;;;;;;;;4BAYS;CAC3B,CAAC,CAAA;AAEF;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAC,OAAe,EAAE,KAAgB,EAAE,OAAe;IAC3E,OAAO,OAAO,CAAC,OAAO,CACpB,gBAAgB,KAAK,EAAE,EACvB,8BAA8B,OAAO,IAAI,KAAK,EAAE,CACjD,CAAA;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,EAAgB,EAAE,OAAe;IACnE,KAAK,MAAM,KAAK,IAAI,WAAW,EAAE,CAAC;QAChC,MAAM,GAAG,GAAG,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,CAAA;QACtD,IAAI,CAAC;YACH,MAAM,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;QACvB,CAAC;QACD,OAAO,KAAK,EAAE,CAAC;YACb,MAAM,IAAI,cAAc,CACtB,kBAAkB,EAClB,iCAAiC,KAAK,EAAE,EACxC,KAAK,CACN,CAAA;QACH,CAAC;IACH,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"schemas.js","sourceRoot":"","sources":["../../src/core/schemas.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAGzC,qEAAqE;AACrE,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,KAAK;IACL,YAAY;IACZ,MAAM;IACN,aAAa;IACb,UAAU;IACV,iBAAiB;IACjB,eAAe;IACf,aAAa;IACb,WAAW;IACX,cAAc;IACd,eAAe;IACf,SAAS;IACT,gBAAgB;IAChB,iBAAiB;CACT,CAAA;AAIV;;;GAGG;AACH,MAAM,CAAC,MAAM,OAAO,GAAwC,MAAM,CAAC,MAAM,CAAC;IACxE,GAAG,EAAE;;;;;;;;;;;qCAW8B;IAEnC,UAAU,EAAE;;;;;;;qCAOuB;IAEnC,IAAI,EAAE;;;;;;;qCAO6B;IAEnC,WAAW,EAAE;;;;;;;qCAOsB;IAEnC,QAAQ,EAAE;;;;;;;qCAOyB;IAEnC,eAAe,EAAE;;;;;;;;qCAQkB;IAEnC,aAAa,EAAE;;;;;;;;;;;;;;;2CAe0B;IAEzC,WAAW,EAAE;;;;;;;;;qCASsB;IAEnC,SAAS,EAAE;;;;;;;;;mDASsC;IAEjD,YAAY,EAAE;;;;;;;;4BAQY;IAE1B,aAAa,EAAE;;;;;;;;;;;;;GAad;IAED,OAAO,EAAE;;;;;;;;;;;;4BAYiB;IAE1B,cAAc,EAAE;;;;;;;;GAQf;IAED,eAAe,EAAE;;;;;;;;;;;;4BAYS;CAC3B,CAAC,CAAA;AAEF;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAC,OAAe,EAAE,KAAgB,EAAE,OAAe;IAC3E,OAAO,OAAO,CAAC,OAAO,CACpB,gBAAgB,KAAK,EAAE,EACvB,8BAA8B,OAAO,IAAI,KAAK,EAAE,CACjD,CAAA;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,UAAU,CAAC,OAAe;IACxC,OAAO,OAAO,CAAC,OAAO,CAAC,oCAAoC,EAAE,IAAI,CAAC,CAAA;AACpE,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,MAAM,aAAa,GAAwC,MAAM,CAAC,MAAM,CAC7E,MAAM,CAAC,WAAW,CAChB,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CACjC,CAC/B,CAAA;AAED;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,EAAgB,EAChB,OAAe,EACf,UAA+C,OAAO;IAEtD,KAAK,MAAM,KAAK,IAAI,WAAW,EAAE,CAAC;QAChC,MAAM,GAAG,GAAG,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,CAAA;QACtD,IAAI,CAAC;YACH,MAAM,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;QACvB,CAAC;QACD,OAAO,KAAK,EAAE,CAAC;YACb,MAAM,IAAI,cAAc,CACtB,kBAAkB,EAClB,iCAAiC,KAAK,EAAE,EACxC,KAAK,CACN,CAAA;QACH,CAAC;IACH,CAAC;AACH,CAAC"}
@@ -67,13 +67,24 @@ export interface EventBus {
67
67
  subscribe<T>(name: string, handler: (payload: T) => void): Unsubscribe;
68
68
  subscribePattern<T>(pattern: string, handler: (name: string, payload: T) => void): Unsubscribe;
69
69
  }
70
- export interface AnalyticsConfig {
70
+ /**
71
+ * Attach mode — whether to wire a remote R2 Iceberg catalog (`'r2'`) or
72
+ * operate against local DuckDB only (`'local'`). Default `'r2'` for
73
+ * back-compat with 0.4.x consumers.
74
+ *
75
+ * In `'local'` mode:
76
+ * - `iceberg` + `httpfs` extensions are NOT loaded (removes the AWSSDK
77
+ * / vcpkg build burden on iOS + Android; apps that don't need remote
78
+ * sync can skip building those extensions entirely).
79
+ * - `attach()` transitions straight to `attached` after ensuring the
80
+ * local tables exist; no R2 auth handshake, no remote catalog.
81
+ * - `pusher` / `fetcher` in `@mongrov/analytics/sync` are no-ops.
82
+ * - Rules engine still runs on batch (local-only violation detection).
83
+ */
84
+ export type AnalyticsMode = 'local' | 'r2';
85
+ interface CommonAnalyticsConfig {
71
86
  storage: KVStore;
72
87
  logger?: AnalyticsLogger;
73
- warehouseUriBuilder: (brand: string, tenantScope: TenantScope, tenantId: string) => string;
74
- catalogEndpoint: string;
75
- tokenVendor: TokenVendor;
76
- familyMembersProvider: FamilyMembersProvider;
77
88
  retention: Record<string, {
78
89
  days: number;
79
90
  }>;
@@ -85,6 +96,25 @@ export interface AnalyticsConfig {
85
96
  };
86
97
  eventBus?: EventBus;
87
98
  }
99
+ /**
100
+ * Local-only config. Omits the R2 fields; `mode` is required as the
101
+ * discriminant so consumers explicitly opt in.
102
+ */
103
+ export interface LocalAnalyticsConfig extends CommonAnalyticsConfig {
104
+ mode: 'local';
105
+ }
106
+ /**
107
+ * Remote R2 Iceberg config. `mode` is optional and defaults to `'r2'` for
108
+ * back-compat with 0.4.x call sites that don't set it.
109
+ */
110
+ export interface R2AnalyticsConfig extends CommonAnalyticsConfig {
111
+ mode?: 'r2';
112
+ warehouseUriBuilder: (brand: string, tenantScope: TenantScope, tenantId: string) => string;
113
+ catalogEndpoint: string;
114
+ tokenVendor: TokenVendor;
115
+ familyMembersProvider: FamilyMembersProvider;
116
+ }
117
+ export type AnalyticsConfig = LocalAnalyticsConfig | R2AnalyticsConfig;
88
118
  export interface AnalyticsAppender {
89
119
  appendRow(values: unknown[]): void;
90
120
  flush(): void;
@@ -101,6 +131,13 @@ export interface AnalyticsEngine {
101
131
  readonly lastError: Error | null;
102
132
  /** Catalog / warehouse secret name for the current attach; undefined when not attached. */
103
133
  readonly catalog: string | undefined;
134
+ /**
135
+ * Resolved mode — `'local'` if `AnalyticsConfig.mode === 'local'`,
136
+ * `'r2'` otherwise (including undefined for back-compat). Consumers can
137
+ * use this to gate mode-specific work — e.g. `createSyncManager` skips
138
+ * wiring the R2 pusher/fetcher in local mode.
139
+ */
140
+ readonly mode: AnalyticsMode;
104
141
  subscribe(listener: (s: AnalyticsState) => void): Unsubscribe;
105
142
  setRetention(days: number): Promise<void>;
106
143
  /**
@@ -128,4 +165,5 @@ export interface Insight {
128
165
  thresholdValue?: number;
129
166
  payload?: Record<string, unknown>;
130
167
  }
168
+ export {};
131
169
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"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"}
@@ -1,11 +1,17 @@
1
1
  /**
2
- * Warehouse attach / detach for a single tenant zone.
2
+ * Warehouse attach / detach.
3
3
  *
4
- * Attaches R2 Iceberg data as a named DuckDB catalog, so downstream code can
5
- * `SELECT ... FROM zone_<tenantId>.<table>`. The full sequence lives here so
6
- * the state machine (T-09) can invoke it as a single actor step.
4
+ * Two modes:
5
+ * - `attachWarehouse` (R2 mode): attaches R2 Iceberg data as a named
6
+ * DuckDB catalog, so downstream code can address remote tables via
7
+ * `<zone_<tenantId>>.default.<table>` (3-part names).
8
+ * - `attachLocal` (local mode): no ATTACH; local tables live in the
9
+ * current file-backed catalog. Returns a synthetic `AttachResult`
10
+ * whose `warehouseSecret` is the local catalog name (probed via
11
+ * `current_database()`), so downstream state-machine code keeps the
12
+ * same shape.
7
13
  *
8
- * Sequence per spec §Attach Protocol:
14
+ * Sequence for `attachWarehouse` per spec §Attach Protocol:
9
15
  * 1. Build warehouse URI via `warehouseUriBuilder(brand, scope, tenantId)`.
10
16
  * 2. Fetch bearer token via `tokenVendor.fetch({ brand, scope, tenantId })`.
11
17
  * 3. `CREATE OR REPLACE SECRET` bound to the catalog endpoint + bearer token.
@@ -13,6 +19,16 @@
13
19
  * 5. If `tenantScope === 'family'`, prime member ids via
14
20
  * `familyMembersProvider({ brand, familyId })` (for retention math).
15
21
  *
22
+ * NOTE: 0.5.0 dropped the previous `USE ${secretName}.default` step
23
+ * inside attach + the matching `USE memory.main` before detach. Rationale:
24
+ * `USE memory.main` fails on file-backed DuckDB (real devices open a
25
+ * `.duckdb` file → catalog name is the file stem, not `memory`), and the
26
+ * `USE remote` step made unqualified queries resolve to the remote
27
+ * catalog — silently breaking the pusher's `main.<table>` SQL by pointing
28
+ * `main` at the remote instead of local. Callers should address remote
29
+ * tables via 3-part names (`<secret>.default.<table>`); local tables stay
30
+ * addressable via unqualified names.
31
+ *
16
32
  * All failures map to `AnalyticsError('attach_failed' | 'token_vendor_failed',
17
33
  * <phase>, cause)`.
18
34
  */
@@ -53,6 +69,40 @@ export declare function attachWarehouse(db: HybridDuckDB, ctx: AttachContext, de
53
69
  * Reverse of `attachWarehouse`: `DETACH` the catalog then drop its secret.
54
70
  * Idempotent from the caller's perspective — a `DETACH` of an unknown alias
55
71
  * throws in DuckDB, but the machine only calls this from `attached`.
72
+ *
73
+ * Since 0.5.0's attach no longer switches the current catalog with
74
+ * `USE ${secretName}.default`, this detach no longer needs to reset via
75
+ * `USE memory.main` (which failed on file-backed DuckDB anyway — the
76
+ * catalog on a real device is `<filestem>`, not `memory`).
56
77
  */
57
78
  export declare function detachWarehouse(db: HybridDuckDB, tenantId: string): Promise<void>;
79
+ /**
80
+ * Local-mode "attach" — no ATTACH statement, no auth, no remote catalog.
81
+ * The consumer's DuckDB (in-memory or file-backed) is already the current
82
+ * catalog after `db.open()`; we just probe its name and return a synthetic
83
+ * `AttachResult`. Table creation is deferred to `ensureMigrations` (called
84
+ * next by the factory) so schema evolution stays in one place.
85
+ *
86
+ * `warehouseSecret` in the returned result is set to the local catalog
87
+ * name (from `current_database()`) so downstream state-machine code + the
88
+ * public `engine.catalog` getter surface a meaningful identifier. Fields
89
+ * that only make sense for R2 (`warehouseUri`, `tokenExpiresAt`) get
90
+ * sentinel values: URI is `local:`, expiry is far-future so token-refresh
91
+ * timers never fire.
92
+ */
93
+ export declare function attachLocal(db: HybridDuckDB, _ctx: AttachContext): Promise<AttachResult>;
94
+ /**
95
+ * Probe the current DuckDB catalog name (via `SELECT current_database()`).
96
+ * Used by R2 mode too — the pusher needs to know the local catalog name so
97
+ * its `INSERT INTO r2.default.<table> SELECT * FROM <local>.main.<table>`
98
+ * addresses the correct source (post-0.5.0 attach no longer switches the
99
+ * current catalog, so `main.<table>` still means local).
100
+ */
101
+ export declare function probeLocalCatalog(db: HybridDuckDB): Promise<string>;
102
+ /**
103
+ * Reverse of `attachLocal` — no-op. Local mode never issued any ATTACH /
104
+ * SECRET, so there's nothing to unwind. Kept as an explicit function so
105
+ * the state machine's `detachEngine` actor can dispatch symmetrically.
106
+ */
107
+ export declare function detachLocal(_db: HybridDuckDB, _tenantId: string): Promise<void>;
58
108
  //# sourceMappingURL=warehouse.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"warehouse.d.ts","sourceRoot":"","sources":["../../src/core/warehouse.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAC5C,OAAO,KAAK,EACV,aAAa,EACb,qBAAqB,EACrB,WAAW,EAEX,WAAW,EACZ,MAAM,SAAS,CAAA;AAchB,mFAAmF;AACnF,MAAM,WAAW,UAAU;IACzB,mBAAmB,EAAE,CACnB,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,WAAW,EACxB,QAAQ,EAAE,MAAM,KACb,MAAM,CAAA;IACX,WAAW,EAAE,WAAW,CAAA;IACxB,qBAAqB,EAAE,qBAAqB,CAAA;IAC5C,eAAe,EAAE,MAAM,CAAA;CACxB;AAED,8EAA8E;AAC9E,MAAM,WAAW,YAAY;IAC3B,yDAAyD;IACzD,eAAe,EAAE,MAAM,CAAA;IACvB,8CAA8C;IAC9C,YAAY,EAAE,MAAM,CAAA;IACpB,sEAAsE;IACtE,cAAc,EAAE,IAAI,CAAA;IACpB,sDAAsD;IACtD,eAAe,CAAC,EAAE,MAAM,EAAE,CAAA;CAC3B;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED;;;;;GAKG;AACH,wBAAsB,eAAe,CACnC,EAAE,EAAE,YAAY,EAChB,GAAG,EAAE,aAAa,EAClB,IAAI,EAAE,UAAU,GACf,OAAO,CAAC,YAAY,CAAC,CA8FvB;AAED;;;;GAIG;AACH,wBAAsB,eAAe,CACnC,EAAE,EAAE,YAAY,EAChB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC,CAiBf"}
1
+ {"version":3,"file":"warehouse.d.ts","sourceRoot":"","sources":["../../src/core/warehouse.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAC5C,OAAO,KAAK,EACV,aAAa,EACb,qBAAqB,EACrB,WAAW,EAEX,WAAW,EACZ,MAAM,SAAS,CAAA;AAchB,mFAAmF;AACnF,MAAM,WAAW,UAAU;IACzB,mBAAmB,EAAE,CACnB,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,WAAW,EACxB,QAAQ,EAAE,MAAM,KACb,MAAM,CAAA;IACX,WAAW,EAAE,WAAW,CAAA;IACxB,qBAAqB,EAAE,qBAAqB,CAAA;IAC5C,eAAe,EAAE,MAAM,CAAA;CACxB;AAED,8EAA8E;AAC9E,MAAM,WAAW,YAAY;IAC3B,yDAAyD;IACzD,eAAe,EAAE,MAAM,CAAA;IACvB,8CAA8C;IAC9C,YAAY,EAAE,MAAM,CAAA;IACpB,sEAAsE;IACtE,cAAc,EAAE,IAAI,CAAA;IACpB,sDAAsD;IACtD,eAAe,CAAC,EAAE,MAAM,EAAE,CAAA;CAC3B;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED;;;;;GAKG;AACH,wBAAsB,eAAe,CACnC,EAAE,EAAE,YAAY,EAChB,GAAG,EAAE,aAAa,EAClB,IAAI,EAAE,UAAU,GACf,OAAO,CAAC,YAAY,CAAC,CA0FvB;AAED;;;;;;;;;GASG;AACH,wBAAsB,eAAe,CACnC,EAAE,EAAE,YAAY,EAChB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC,CAaf;AAID;;;;;;;;;;;;;GAaG;AACH,wBAAsB,WAAW,CAC/B,EAAE,EAAE,YAAY,EAChB,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,YAAY,CAAC,CA8BvB;AAED;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CAAC,EAAE,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,CAczE;AAED;;;;GAIG;AACH,wBAAsB,WAAW,CAC/B,GAAG,EAAE,YAAY,EACjB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC,CAEf"}
@@ -1,11 +1,17 @@
1
1
  /**
2
- * Warehouse attach / detach for a single tenant zone.
2
+ * Warehouse attach / detach.
3
3
  *
4
- * Attaches R2 Iceberg data as a named DuckDB catalog, so downstream code can
5
- * `SELECT ... FROM zone_<tenantId>.<table>`. The full sequence lives here so
6
- * the state machine (T-09) can invoke it as a single actor step.
4
+ * Two modes:
5
+ * - `attachWarehouse` (R2 mode): attaches R2 Iceberg data as a named
6
+ * DuckDB catalog, so downstream code can address remote tables via
7
+ * `<zone_<tenantId>>.default.<table>` (3-part names).
8
+ * - `attachLocal` (local mode): no ATTACH; local tables live in the
9
+ * current file-backed catalog. Returns a synthetic `AttachResult`
10
+ * whose `warehouseSecret` is the local catalog name (probed via
11
+ * `current_database()`), so downstream state-machine code keeps the
12
+ * same shape.
7
13
  *
8
- * Sequence per spec §Attach Protocol:
14
+ * Sequence for `attachWarehouse` per spec §Attach Protocol:
9
15
  * 1. Build warehouse URI via `warehouseUriBuilder(brand, scope, tenantId)`.
10
16
  * 2. Fetch bearer token via `tokenVendor.fetch({ brand, scope, tenantId })`.
11
17
  * 3. `CREATE OR REPLACE SECRET` bound to the catalog endpoint + bearer token.
@@ -13,6 +19,16 @@
13
19
  * 5. If `tenantScope === 'family'`, prime member ids via
14
20
  * `familyMembersProvider({ brand, familyId })` (for retention math).
15
21
  *
22
+ * NOTE: 0.5.0 dropped the previous `USE ${secretName}.default` step
23
+ * inside attach + the matching `USE memory.main` before detach. Rationale:
24
+ * `USE memory.main` fails on file-backed DuckDB (real devices open a
25
+ * `.duckdb` file → catalog name is the file stem, not `memory`), and the
26
+ * `USE remote` step made unqualified queries resolve to the remote
27
+ * catalog — silently breaking the pusher's `main.<table>` SQL by pointing
28
+ * `main` at the remote instead of local. Callers should address remote
29
+ * tables via 3-part names (`<secret>.default.<table>`); local tables stay
30
+ * addressable via unqualified names.
31
+ *
16
32
  * All failures map to `AnalyticsError('attach_failed' | 'token_vendor_failed',
17
33
  * <phase>, cause)`.
18
34
  */
@@ -71,17 +87,13 @@ export async function attachWarehouse(db, ctx, deps) {
71
87
  catch (cause) {
72
88
  throw new AnalyticsError('attach_failed', `CREATE SECRET failed for ${secretName}`, rootCause(cause));
73
89
  }
74
- // Step 4: ATTACH + pin the current schema to the `default` namespace.
75
- //
76
- // DuckDB's Iceberg attach does not select a namespace, so unqualified
77
- // `<catalog>.<table>` DDL (see `schemas.ts` / `qualifyDdl`) would resolve
78
- // against schema `""` and fail with `Schema with name "" not found`.
79
- // Iceberg mandates 3-part names; picking `default` here lets the rest of
80
- // the codebase keep the 2-part `<catalog>.<table>` shape it was written
81
- // against. Callers that need a different namespace should attach directly.
90
+ // Step 4: ATTACH. See top-of-file NOTE for why the prior
91
+ // `USE ${secretName}.default` step was dropped in 0.5.0. Consumers write
92
+ // to the remote via 3-part names (`${secretName}.default.<table>`), keeping
93
+ // local `main.<table>` addressable for the pusher's SELECT source and the
94
+ // rules engine's INSERT sink.
82
95
  try {
83
96
  await db.execute(`ATTACH '${uri}' AS ${secretName} (TYPE ICEBERG);`);
84
- await db.execute(`USE ${secretName}.default;`);
85
97
  }
86
98
  catch (cause) {
87
99
  throw new AnalyticsError('attach_failed', `ATTACH failed for ${secretName}`, rootCause(cause));
@@ -110,14 +122,15 @@ export async function attachWarehouse(db, ctx, deps) {
110
122
  * Reverse of `attachWarehouse`: `DETACH` the catalog then drop its secret.
111
123
  * Idempotent from the caller's perspective — a `DETACH` of an unknown alias
112
124
  * throws in DuckDB, but the machine only calls this from `attached`.
125
+ *
126
+ * Since 0.5.0's attach no longer switches the current catalog with
127
+ * `USE ${secretName}.default`, this detach no longer needs to reset via
128
+ * `USE memory.main` (which failed on file-backed DuckDB anyway — the
129
+ * catalog on a real device is `<filestem>`, not `memory`).
113
130
  */
114
131
  export async function detachWarehouse(db, tenantId) {
115
132
  const secretName = warehouseSecretName(tenantId);
116
133
  try {
117
- // DuckDB refuses to detach the current default database, and `attach`
118
- // above pinned it to `${secretName}.default`. Reset to the in-memory
119
- // catalog before detaching so DETACH succeeds.
120
- await db.execute(`USE memory.main;`);
121
134
  await db.execute(`DETACH ${secretName};`);
122
135
  await db.execute(`DROP SECRET ${secretName};`);
123
136
  }
@@ -125,4 +138,66 @@ export async function detachWarehouse(db, tenantId) {
125
138
  throw new AnalyticsError('detach_failed', `detach failed for ${secretName}`, rootCause(cause));
126
139
  }
127
140
  }
141
+ // -------------------- local mode --------------------
142
+ /**
143
+ * Local-mode "attach" — no ATTACH statement, no auth, no remote catalog.
144
+ * The consumer's DuckDB (in-memory or file-backed) is already the current
145
+ * catalog after `db.open()`; we just probe its name and return a synthetic
146
+ * `AttachResult`. Table creation is deferred to `ensureMigrations` (called
147
+ * next by the factory) so schema evolution stays in one place.
148
+ *
149
+ * `warehouseSecret` in the returned result is set to the local catalog
150
+ * name (from `current_database()`) so downstream state-machine code + the
151
+ * public `engine.catalog` getter surface a meaningful identifier. Fields
152
+ * that only make sense for R2 (`warehouseUri`, `tokenExpiresAt`) get
153
+ * sentinel values: URI is `local:`, expiry is far-future so token-refresh
154
+ * timers never fire.
155
+ */
156
+ export async function attachLocal(db, _ctx) {
157
+ // Probe the current catalog name so downstream code addresses local
158
+ // tables via `${catalog}.main.<table>` when it needs to be explicit.
159
+ let catalog;
160
+ try {
161
+ const rows = await db.execute(`SELECT current_database() AS current_database;`);
162
+ catalog = rows[0]?.current_database ?? 'memory';
163
+ }
164
+ catch (cause) {
165
+ throw new AnalyticsError('attach_failed', `attachLocal: current_database() probe failed`, rootCause(cause));
166
+ }
167
+ // Sentinel expiry — 100 years from now. Token-refresh scheduling in the
168
+ // state machine keys off this; setting it far-future prevents the
169
+ // refresh actor from ever firing in local mode.
170
+ const farFuture = new Date(Date.now() + 100 * 365 * 24 * 60 * 60 * 1000);
171
+ return {
172
+ warehouseSecret: catalog,
173
+ warehouseUri: 'local:',
174
+ tokenExpiresAt: farFuture,
175
+ // No family fanout in local mode; retention math falls back to ctx.userId.
176
+ familyMemberIds: undefined,
177
+ };
178
+ }
179
+ /**
180
+ * Probe the current DuckDB catalog name (via `SELECT current_database()`).
181
+ * Used by R2 mode too — the pusher needs to know the local catalog name so
182
+ * its `INSERT INTO r2.default.<table> SELECT * FROM <local>.main.<table>`
183
+ * addresses the correct source (post-0.5.0 attach no longer switches the
184
+ * current catalog, so `main.<table>` still means local).
185
+ */
186
+ export async function probeLocalCatalog(db) {
187
+ try {
188
+ const rows = await db.execute(`SELECT current_database() AS current_database;`);
189
+ return rows[0]?.current_database ?? 'memory';
190
+ }
191
+ catch (cause) {
192
+ throw new AnalyticsError('query_failed', `probeLocalCatalog: current_database() failed`, rootCause(cause));
193
+ }
194
+ }
195
+ /**
196
+ * Reverse of `attachLocal` — no-op. Local mode never issued any ATTACH /
197
+ * SECRET, so there's nothing to unwind. Kept as an explicit function so
198
+ * the state machine's `detachEngine` actor can dispatch symmetrically.
199
+ */
200
+ export async function detachLocal(_db, _tenantId) {
201
+ // intentional no-op
202
+ }
128
203
  //# sourceMappingURL=warehouse.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"warehouse.js","sourceRoot":"","sources":["../../src/core/warehouse.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"warehouse.js","sourceRoot":"","sources":["../../src/core/warehouse.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import type { AnalyticsEngine } from '../../core/types';
1
+ import type { AnalyticsEngine, AnalyticsState } from '../../core/types';
2
2
  /** Minimal AnalyticsEngine stub for evaluator tests. */
3
3
  export interface FakeEngine extends AnalyticsEngine {
4
4
  __calls: {
@@ -7,6 +7,8 @@ export interface FakeEngine extends AnalyticsEngine {
7
7
  }[];
8
8
  __setResult(rows: unknown[]): void;
9
9
  __setError(err: Error | null): void;
10
+ /** Mutate the reported `state` for tests that exercise the attached-state guard. */
11
+ __setState(state: AnalyticsState): void;
10
12
  }
11
13
  export declare function createFakeEngine(): FakeEngine;
12
14
  //# sourceMappingURL=fakeEngine.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"fakeEngine.d.ts","sourceRoot":"","sources":["../../../src/rules/__fakes__/fakeEngine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAEvD,wDAAwD;AACxD,MAAM,WAAW,UAAW,SAAQ,eAAe;IACjD,OAAO,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,EAAE,CAAA;IAC3D,WAAW,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAA;IAClC,UAAU,CAAC,GAAG,EAAE,KAAK,GAAG,IAAI,GAAG,IAAI,CAAA;CACpC;AAED,wBAAgB,gBAAgB,IAAI,UAAU,CA+B7C"}
1
+ {"version":3,"file":"fakeEngine.d.ts","sourceRoot":"","sources":["../../../src/rules/__fakes__/fakeEngine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAEvE,wDAAwD;AACxD,MAAM,WAAW,UAAW,SAAQ,eAAe;IACjD,OAAO,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,EAAE,CAAA;IAC3D,WAAW,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAA;IAClC,UAAU,CAAC,GAAG,EAAE,KAAK,GAAG,IAAI,GAAG,IAAI,CAAA;IACnC,oFAAoF;IACpF,UAAU,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI,CAAA;CACxC;AAED,wBAAgB,gBAAgB,IAAI,UAAU,CAkC7C"}
@@ -1,6 +1,7 @@
1
1
  export function createFakeEngine() {
2
2
  let queued = [];
3
3
  let queuedErr = null;
4
+ let state = 'attached';
4
5
  const calls = [];
5
6
  const engine = {
6
7
  async attach() { },
@@ -17,9 +18,10 @@ export function createFakeEngine() {
17
18
  createAppender() {
18
19
  throw new Error('createAppender not implemented in fake');
19
20
  },
20
- state: 'attached',
21
+ get state() { return state; },
21
22
  lastError: null,
22
23
  catalog: 'fake',
24
+ mode: 'r2',
23
25
  subscribe: () => () => { },
24
26
  async setRetention() { },
25
27
  async getLastAttach() { return null; },
@@ -27,6 +29,7 @@ export function createFakeEngine() {
27
29
  __calls: calls,
28
30
  __setResult(rows) { queued = rows; queuedErr = null; },
29
31
  __setError(err) { queuedErr = err; },
32
+ __setState(s) { state = s; },
30
33
  };
31
34
  return engine;
32
35
  }
@@ -1 +1 @@
1
- {"version":3,"file":"fakeEngine.js","sourceRoot":"","sources":["../../../src/rules/__fakes__/fakeEngine.ts"],"names":[],"mappings":"AASA,MAAM,UAAU,gBAAgB;IAC9B,IAAI,MAAM,GAAc,EAAE,CAAA;IAC1B,IAAI,SAAS,GAAiB,IAAI,CAAA;IAClC,MAAM,KAAK,GAAuD,EAAE,CAAA;IAEpE,MAAM,MAAM,GAAe;QACzB,KAAK,CAAC,MAAM,KAAI,CAAC;QACjB,KAAK,CAAC,MAAM,KAAI,CAAC;QACjB,KAAK,CAAC,OAAO,CAAI,GAAW,EAAE,MAAgC;YAC5D,KAAK,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,IAAI,EAAE,EAAE,CAAC,CAAA;YACzC,IAAI,SAAS;gBAAE,MAAM,SAAS,CAAA;YAC9B,OAAO,MAAa,CAAA;QACtB,CAAC;QACD,MAAM;YACJ,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAA;QACnD,CAAC;QACD,cAAc;YACZ,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAA;QAC3D,CAAC;QACD,KAAK,EAAE,UAAU;QACjB,SAAS,EAAE,IAAI;QACf,OAAO,EAAE,MAAM;QACf,SAAS,EAAE,GAAG,EAAE,CAAC,GAAG,EAAE,GAAE,CAAC;QACzB,KAAK,CAAC,YAAY,KAAI,CAAC;QACvB,KAAK,CAAC,aAAa,KAAK,OAAO,IAAI,CAAA,CAAC,CAAC;QACrC,KAAK,CAAC,KAAK,KAAI,CAAC;QAChB,OAAO,EAAE,KAAK;QACd,WAAW,CAAC,IAAI,IAAI,MAAM,GAAG,IAAI,CAAC,CAAC,SAAS,GAAG,IAAI,CAAA,CAAC,CAAC;QACrD,UAAU,CAAC,GAAG,IAAI,SAAS,GAAG,GAAG,CAAA,CAAC,CAAC;KACpC,CAAA;IACD,OAAO,MAAM,CAAA;AACf,CAAC"}
1
+ {"version":3,"file":"fakeEngine.js","sourceRoot":"","sources":["../../../src/rules/__fakes__/fakeEngine.ts"],"names":[],"mappings":"AAWA,MAAM,UAAU,gBAAgB;IAC9B,IAAI,MAAM,GAAc,EAAE,CAAA;IAC1B,IAAI,SAAS,GAAiB,IAAI,CAAA;IAClC,IAAI,KAAK,GAAmB,UAAU,CAAA;IACtC,MAAM,KAAK,GAAuD,EAAE,CAAA;IAEpE,MAAM,MAAM,GAAe;QACzB,KAAK,CAAC,MAAM,KAAI,CAAC;QACjB,KAAK,CAAC,MAAM,KAAI,CAAC;QACjB,KAAK,CAAC,OAAO,CAAI,GAAW,EAAE,MAAgC;YAC5D,KAAK,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,IAAI,EAAE,EAAE,CAAC,CAAA;YACzC,IAAI,SAAS;gBAAE,MAAM,SAAS,CAAA;YAC9B,OAAO,MAAa,CAAA;QACtB,CAAC;QACD,MAAM;YACJ,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAA;QACnD,CAAC;QACD,cAAc;YACZ,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAA;QAC3D,CAAC;QACD,IAAI,KAAK,KAAK,OAAO,KAAK,CAAA,CAAC,CAAC;QAC5B,SAAS,EAAE,IAAI;QACf,OAAO,EAAE,MAAM;QACf,IAAI,EAAE,IAAI;QACV,SAAS,EAAE,GAAG,EAAE,CAAC,GAAG,EAAE,GAAE,CAAC;QACzB,KAAK,CAAC,YAAY,KAAI,CAAC;QACvB,KAAK,CAAC,aAAa,KAAK,OAAO,IAAI,CAAA,CAAC,CAAC;QACrC,KAAK,CAAC,KAAK,KAAI,CAAC;QAChB,OAAO,EAAE,KAAK;QACd,WAAW,CAAC,IAAI,IAAI,MAAM,GAAG,IAAI,CAAC,CAAC,SAAS,GAAG,IAAI,CAAA,CAAC,CAAC;QACrD,UAAU,CAAC,GAAG,IAAI,SAAS,GAAG,GAAG,CAAA,CAAC,CAAC;QACnC,UAAU,CAAC,CAAC,IAAI,KAAK,GAAG,CAAC,CAAA,CAAC,CAAC;KAC5B,CAAA;IACD,OAAO,MAAM,CAAA;AACf,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../../src/rules/defaults/loader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,EAAmC,KAAK,IAAI,EAAE,MAAM,WAAW,CAAA;AAMtE,MAAM,WAAW,mBAAmB;IAClC,sEAAsE;IACtE,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED,wBAAgB,YAAY,CAC1B,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,mBAAmB,GAC5B,IAAI,EAAE,CA8BR"}
1
+ {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../../src/rules/defaults/loader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,OAAO,EAAmC,KAAK,IAAI,EAAE,MAAM,WAAW,CAAA;AAMtE,MAAM,WAAW,mBAAmB;IAClC,sEAAsE;IACtE,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED,wBAAgB,YAAY,CAC1B,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,mBAAmB,GAC5B,IAAI,EAAE,CA8BR"}
@@ -9,13 +9,15 @@
9
9
  * a `RuleValidationError` with a catalog-aware prefix so consumers can
10
10
  * locate the offending brand file.
11
11
  */
12
- import TOML from '@iarna/toml';
12
+ // Direct import of parse-string avoids the parse.js -> parse-stream.js ->
13
+ // require('stream') chain that breaks Metro (React Native has no Node stdlib).
14
+ import parseString from '@iarna/toml/parse-string.js';
13
15
  import { RuleSchema, RuleValidationError } from '../schema';
14
16
  export function parseCatalog(toml, options) {
15
17
  const label = options?.name ?? 'catalog';
16
18
  let doc;
17
19
  try {
18
- doc = TOML.parse(toml);
20
+ doc = parseString(toml);
19
21
  }
20
22
  catch (err) {
21
23
  throw new RuleValidationError(`${label}: TOML parse error — ${err.message}`);
@@ -1 +1 @@
1
- {"version":3,"file":"loader.js","sourceRoot":"","sources":["../../../src/rules/defaults/loader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,IAAI,MAAM,aAAa,CAAA;AAC9B,OAAO,EAAE,UAAU,EAAE,mBAAmB,EAAa,MAAM,WAAW,CAAA;AAWtE,MAAM,UAAU,YAAY,CAC1B,IAAY,EACZ,OAA6B;IAE7B,MAAM,KAAK,GAAG,OAAO,EAAE,IAAI,IAAI,SAAS,CAAA;IACxC,IAAI,GAAe,CAAA;IACnB,IAAI,CAAC;QACH,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAe,CAAA;IACtC,CAAC;IACD,OAAO,GAAG,EAAE,CAAC;QACX,MAAM,IAAI,mBAAmB,CAC3B,GAAG,KAAK,wBAAyB,GAAa,CAAC,OAAO,EAAE,CACzD,CAAA;IACH,CAAC;IAED,MAAM,GAAG,GAAG,GAAG,CAAC,IAAI,CAAA;IACpB,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,mBAAmB,CAC3B,GAAG,KAAK,4BAA4B,CACrC,CAAA;IACH,CAAC;IAED,MAAM,KAAK,GAAW,EAAE,CAAA;IACxB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACpC,MAAM,MAAM,GAAG,UAAU,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAA;QAC3C,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,MAAM,IAAI,mBAAmB,CAC3B,GAAG,KAAK,UAAU,CAAC,cAAc,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,CACxD,CAAA;QACH,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IACzB,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC"}
1
+ {"version":3,"file":"loader.js","sourceRoot":"","sources":["../../../src/rules/defaults/loader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,0EAA0E;AAC1E,+EAA+E;AAC/E,OAAO,WAAW,MAAM,6BAA6B,CAAA;AACrD,OAAO,EAAE,UAAU,EAAE,mBAAmB,EAAa,MAAM,WAAW,CAAA;AAWtE,MAAM,UAAU,YAAY,CAC1B,IAAY,EACZ,OAA6B;IAE7B,MAAM,KAAK,GAAG,OAAO,EAAE,IAAI,IAAI,SAAS,CAAA;IACxC,IAAI,GAAe,CAAA;IACnB,IAAI,CAAC;QACH,GAAG,GAAG,WAAW,CAAC,IAAI,CAAe,CAAA;IACvC,CAAC;IACD,OAAO,GAAG,EAAE,CAAC;QACX,MAAM,IAAI,mBAAmB,CAC3B,GAAG,KAAK,wBAAyB,GAAa,CAAC,OAAO,EAAE,CACzD,CAAA;IACH,CAAC;IAED,MAAM,GAAG,GAAG,GAAG,CAAC,IAAI,CAAA;IACpB,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,mBAAmB,CAC3B,GAAG,KAAK,4BAA4B,CACrC,CAAA;IACH,CAAC;IAED,MAAM,KAAK,GAAW,EAAE,CAAA;IACxB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACpC,MAAM,MAAM,GAAG,UAAU,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAA;QAC3C,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,MAAM,IAAI,mBAAmB,CAC3B,GAAG,KAAK,UAAU,CAAC,cAAc,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,CACxD,CAAA;QACH,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IACzB,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC"}
@@ -11,6 +11,8 @@ type ViolationHandler = (v: RuleViolation) => void;
11
11
  export interface RulesEmitter {
12
12
  on(event: 'violation', handler: ViolationHandler): Unsubscribe;
13
13
  emit(event: 'violation', payload: RuleViolation): void;
14
+ /** Drop every subscriber. Idempotent. Used by `RulesEngine.close()`. */
15
+ close(): void;
14
16
  }
15
17
  export interface CreateEmitterConfig {
16
18
  logger?: RulesLogger;
@@ -1 +1 @@
1
- {"version":3,"file":"emitter.d.ts","sourceRoot":"","sources":["../../src/rules/emitter.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAChD,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AAEzD,KAAK,gBAAgB,GAAG,CAAC,CAAC,EAAE,aAAa,KAAK,IAAI,CAAA;AAElD,MAAM,WAAW,YAAY;IAC3B,EAAE,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,gBAAgB,GAAG,WAAW,CAAA;IAC9D,IAAI,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,aAAa,GAAG,IAAI,CAAA;CACvD;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,CAAC,EAAE,WAAW,CAAA;CACrB;AAED,wBAAgB,aAAa,CAAC,EAAE,MAAM,EAAE,GAAE,mBAAwB,GAAG,YAAY,CAwBhF"}
1
+ {"version":3,"file":"emitter.d.ts","sourceRoot":"","sources":["../../src/rules/emitter.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAChD,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AAEzD,KAAK,gBAAgB,GAAG,CAAC,CAAC,EAAE,aAAa,KAAK,IAAI,CAAA;AAElD,MAAM,WAAW,YAAY;IAC3B,EAAE,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,gBAAgB,GAAG,WAAW,CAAA;IAC9D,IAAI,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,aAAa,GAAG,IAAI,CAAA;IACtD,wEAAwE;IACxE,KAAK,IAAI,IAAI,CAAA;CACd;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,CAAC,EAAE,WAAW,CAAA;CACrB;AAED,wBAAgB,aAAa,CAAC,EAAE,MAAM,EAAE,GAAE,mBAAwB,GAAG,YAAY,CA2BhF"}
@@ -27,6 +27,9 @@ export function createEmitter({ logger } = {}) {
27
27
  }
28
28
  }
29
29
  },
30
+ close() {
31
+ handlers.clear();
32
+ },
30
33
  };
31
34
  }
32
35
  //# sourceMappingURL=emitter.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"emitter.js","sourceRoot":"","sources":["../../src/rules/emitter.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAgBH,MAAM,UAAU,aAAa,CAAC,EAAE,MAAM,KAA0B,EAAE;IAChE,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAoB,CAAA;IAE5C,OAAO;QACL,EAAE,CAAC,MAAM,EAAE,OAAO;YAChB,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;YACrB,OAAO,GAAG,EAAE;gBACV,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;YAC1B,CAAC,CAAA;QACH,CAAC;QACD,IAAI,CAAC,MAAM,EAAE,OAAO;YAClB,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;gBACzB,IAAI,CAAC;oBACH,CAAC,CAAC,OAAO,CAAC,CAAA;gBACZ,CAAC;gBACD,OAAO,GAAG,EAAE,CAAC;oBACX,MAAM,EAAE,KAAK,CAAC,wCAAwC,EAAE;wBACtD,GAAG,EAAG,GAAa,CAAC,OAAO;wBAC3B,MAAM,EAAE,OAAO,CAAC,MAAM;qBACvB,CAAC,CAAA;gBACJ,CAAC;YACH,CAAC;QACH,CAAC;KACF,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"emitter.js","sourceRoot":"","sources":["../../src/rules/emitter.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAkBH,MAAM,UAAU,aAAa,CAAC,EAAE,MAAM,KAA0B,EAAE;IAChE,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAoB,CAAA;IAE5C,OAAO;QACL,EAAE,CAAC,MAAM,EAAE,OAAO;YAChB,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;YACrB,OAAO,GAAG,EAAE;gBACV,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;YAC1B,CAAC,CAAA;QACH,CAAC;QACD,IAAI,CAAC,MAAM,EAAE,OAAO;YAClB,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;gBACzB,IAAI,CAAC;oBACH,CAAC,CAAC,OAAO,CAAC,CAAA;gBACZ,CAAC;gBACD,OAAO,GAAG,EAAE,CAAC;oBACX,MAAM,EAAE,KAAK,CAAC,wCAAwC,EAAE;wBACtD,GAAG,EAAG,GAAa,CAAC,OAAO;wBAC3B,MAAM,EAAE,OAAO,CAAC,MAAM;qBACvB,CAAC,CAAA;gBACJ,CAAC;YACH,CAAC;QACH,CAAC;QACD,KAAK;YACH,QAAQ,CAAC,KAAK,EAAE,CAAA;QAClB,CAAC;KACF,CAAA;AACH,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"evaluator.d.ts","sourceRoot":"","sources":["../../src/rules/evaluator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AACpD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAA;AAC9C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAE/C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAA;AACrD,OAAO,KAAK,EACV,KAAK,EACL,aAAa,EACb,WAAW,EACX,YAAY,EACb,MAAM,SAAS,CAAA;AAEhB,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,aAAa,CAAA;IACvB,KAAK,EAAE,aAAa,CAAA;IACpB,QAAQ,EAAE,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAA;IAChD,OAAO,EAAE,UAAU,CAAC,OAAO,aAAa,CAAC,CAAA;IACzC,SAAS,EAAE,eAAe,CAAA;IAC1B,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,MAAM,CAAA;IAChB,qBAAqB,EAAE,CAAC,GAAG,EAAE;QAC3B,KAAK,EAAE,MAAM,CAAA;QACb,QAAQ,EAAE,MAAM,CAAA;KACjB,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,CAAA;IACvB,KAAK,EAAE,KAAK,CAAA;IACZ,MAAM,CAAC,EAAE,WAAW,CAAA;CACrB;AAOD,MAAM,WAAW,SAAS;IACxB,eAAe,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAAA;IAC9D,iBAAiB,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC,CAAA;CAC9C;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,eAAe,GAAG,SAAS,CAkIlE"}
1
+ {"version":3,"file":"evaluator.d.ts","sourceRoot":"","sources":["../../src/rules/evaluator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAIH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AACpD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAA;AAC9C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAE/C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAA;AACrD,OAAO,KAAK,EACV,KAAK,EACL,aAAa,EACb,WAAW,EACX,YAAY,EACb,MAAM,SAAS,CAAA;AAEhB,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,aAAa,CAAA;IACvB,KAAK,EAAE,aAAa,CAAA;IACpB,QAAQ,EAAE,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAA;IAChD,OAAO,EAAE,UAAU,CAAC,OAAO,aAAa,CAAC,CAAA;IACzC,SAAS,EAAE,eAAe,CAAA;IAC1B,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,MAAM,CAAA;IAChB,qBAAqB,EAAE,CAAC,GAAG,EAAE;QAC3B,KAAK,EAAE,MAAM,CAAA;QACb,QAAQ,EAAE,MAAM,CAAA;KACjB,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,CAAA;IACvB,KAAK,EAAE,KAAK,CAAA;IACZ,MAAM,CAAC,EAAE,WAAW,CAAA;CACrB;AAOD,MAAM,WAAW,SAAS;IACxB,eAAe,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAAA;IAC9D,iBAAiB,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC,CAAA;CAC9C;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,eAAe,GAAG,SAAS,CAwIlE"}
@@ -16,6 +16,7 @@
16
16
  * blocks the rest of the pass.
17
17
  */
18
18
  import { METRIC_METADATA } from '../core/metric_metadata';
19
+ import { AnalyticsError } from '../core/errors';
19
20
  export function createEvaluator(config) {
20
21
  const { registry, cache, throttle, emitter, analytics, brand, familyId, familyMembersProvider, clock, logger, } = config;
21
22
  async function evaluateRule(rule, ctx) {
@@ -97,6 +98,9 @@ export function createEvaluator(config) {
97
98
  return violations;
98
99
  },
99
100
  async evaluateScheduled() {
101
+ if (analytics.state !== 'attached') {
102
+ throw new AnalyticsError('not_attached', `evaluateScheduled requires an attached analytics engine (state=${analytics.state})`);
103
+ }
100
104
  const active = registry.getByBrand(brand);
101
105
  if (active.length === 0) {
102
106
  return [];
@@ -1 +1 @@
1
- {"version":3,"file":"evaluator.js","sourceRoot":"","sources":["../../src/rules/evaluator.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"evaluator.js","sourceRoot":"","sources":["../../src/rules/evaluator.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../src/rules/factory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAOH,OAAO,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAA;AAE7D,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,iBAAiB,GAAG,WAAW,CAiDxE"}
1
+ {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../src/rules/factory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAOH,OAAO,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAA;AAE7D,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,iBAAiB,GAAG,WAAW,CAsExE"}