@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.
- package/dist/core/errors.js +1 -1
- package/dist/core/errors.js.map +1 -1
- package/dist/core/extensions.d.ts +20 -6
- package/dist/core/extensions.d.ts.map +1 -1
- package/dist/core/extensions.js +21 -7
- package/dist/core/extensions.js.map +1 -1
- package/dist/core/factory.d.ts.map +1 -1
- package/dist/core/factory.js +90 -15
- package/dist/core/factory.js.map +1 -1
- package/dist/core/migrations.d.ts +22 -4
- package/dist/core/migrations.d.ts.map +1 -1
- package/dist/core/migrations.js +46 -7
- package/dist/core/migrations.js.map +1 -1
- package/dist/core/schemas.d.ts +36 -5
- package/dist/core/schemas.d.ts.map +1 -1
- package/dist/core/schemas.js +39 -6
- package/dist/core/schemas.js.map +1 -1
- package/dist/core/types.d.ts +43 -5
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/warehouse.d.ts +55 -5
- package/dist/core/warehouse.d.ts.map +1 -1
- package/dist/core/warehouse.js +93 -18
- package/dist/core/warehouse.js.map +1 -1
- package/dist/rules/__fakes__/fakeEngine.d.ts +3 -1
- package/dist/rules/__fakes__/fakeEngine.d.ts.map +1 -1
- package/dist/rules/__fakes__/fakeEngine.js +4 -1
- package/dist/rules/__fakes__/fakeEngine.js.map +1 -1
- package/dist/rules/defaults/loader.d.ts.map +1 -1
- package/dist/rules/defaults/loader.js +4 -2
- package/dist/rules/defaults/loader.js.map +1 -1
- package/dist/rules/emitter.d.ts +2 -0
- package/dist/rules/emitter.d.ts.map +1 -1
- package/dist/rules/emitter.js +3 -0
- package/dist/rules/emitter.js.map +1 -1
- package/dist/rules/evaluator.d.ts.map +1 -1
- package/dist/rules/evaluator.js +4 -0
- package/dist/rules/evaluator.js.map +1 -1
- package/dist/rules/factory.d.ts.map +1 -1
- package/dist/rules/factory.js +29 -4
- package/dist/rules/factory.js.map +1 -1
- package/dist/rules/registry.d.ts +8 -0
- package/dist/rules/registry.d.ts.map +1 -1
- package/dist/rules/registry.js +22 -0
- package/dist/rules/registry.js.map +1 -1
- package/dist/rules/types.d.ts +9 -0
- package/dist/rules/types.d.ts.map +1 -1
- package/dist/sync/factory.d.ts.map +1 -1
- package/dist/sync/factory.js +20 -7
- package/dist/sync/factory.js.map +1 -1
- package/dist/sync/fetcher.d.ts.map +1 -1
- package/dist/sync/fetcher.js +2 -1
- package/dist/sync/fetcher.js.map +1 -1
- package/dist/sync/pusher.d.ts +10 -3
- package/dist/sync/pusher.d.ts.map +1 -1
- package/dist/sync/pusher.js +1 -1
- package/dist/sync/pusher.js.map +1 -1
- package/dist/tools/__fakes__/engine.d.ts.map +1 -1
- package/dist/tools/__fakes__/engine.js +1 -0
- package/dist/tools/__fakes__/engine.js.map +1 -1
- package/package.json +3 -3
package/dist/core/schemas.js
CHANGED
|
@@ -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
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
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(
|
|
233
|
+
const sql = qualifyDdl(schemas[table], table, catalog);
|
|
201
234
|
try {
|
|
202
235
|
await db.execute(sql);
|
|
203
236
|
}
|
package/dist/core/schemas.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schemas.js","sourceRoot":"","sources":["../../src/core/schemas.ts"],"names":[],"mappings":"AAAA
|
|
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"}
|
package/dist/core/types.d.ts
CHANGED
|
@@ -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
|
-
|
|
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
|
package/dist/core/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,mCAAmC;AACnC,MAAM,MAAM,WAAW,GAAG,MAAM,IAAI,CAAA;AAEpC,gDAAgD;AAChD,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,KAAK,CAAA;AAE1C,+DAA+D;AAC/D,MAAM,MAAM,cAAc,GACtB,MAAM,GACN,SAAS,GACT,OAAO,GACP,WAAW,GACX,UAAU,GACV,WAAW,GACX,OAAO,CAAA;AAIX,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,WAAW,CAAA;IACxB,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,WAAW,CAAA;IACxB,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAA;IACb,SAAS,EAAE,IAAI,CAAA;IACf,WAAW,EAAE;QACX,KAAK,EAAE,MAAM,CAAA;QACb,WAAW,EAAE,WAAW,CAAA;QACxB,QAAQ,EAAE,MAAM,CAAA;QAChB,WAAW,EAAE,CAAC,MAAM,GAAG,OAAO,CAAC,EAAE,CAAA;KAClC,CAAA;CACF;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC,CAAA;CACrD;AAED,8EAA8E;AAC9E,MAAM,MAAM,qBAAqB,GAAG,CAAC,GAAG,EAAE;IACxC,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,MAAM,CAAA;CACjB,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,CAAA;AAIvB,MAAM,WAAW,eAAe;IAC9B,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAA;IAC5D,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAA;IAC3D,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAA;IAC3D,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAA;CAC7D;AAID;;;;GAIG;AACH,MAAM,WAAW,OAAO;IACtB,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CAAA;IACrD,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACtD,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CACnC;AAED;;;;GAIG;AACH,MAAM,WAAW,QAAQ;IACvB,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,IAAI,CAAA;IACvC,SAAS,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,IAAI,GAAG,WAAW,CAAA;IACtE,gBAAgB,CAAC,CAAC,EAChB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,KAAK,IAAI,GAC1C,WAAW,CAAA;CACf;AAID,MAAM,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"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"}
|
package/dist/core/warehouse.d.ts
CHANGED
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Warehouse attach / detach
|
|
2
|
+
* Warehouse attach / detach.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* `
|
|
6
|
-
*
|
|
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
|
|
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"}
|
package/dist/core/warehouse.js
CHANGED
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Warehouse attach / detach
|
|
2
|
+
* Warehouse attach / detach.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* `
|
|
6
|
-
*
|
|
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
|
|
75
|
-
//
|
|
76
|
-
//
|
|
77
|
-
//
|
|
78
|
-
//
|
|
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":"AAAA
|
|
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;
|
|
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
|
|
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":"
|
|
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;
|
|
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
|
|
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 =
|
|
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,
|
|
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"}
|
package/dist/rules/emitter.d.ts
CHANGED
|
@@ -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;
|
|
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"}
|
package/dist/rules/emitter.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"emitter.js","sourceRoot":"","sources":["../../src/rules/emitter.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;
|
|
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;
|
|
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"}
|
package/dist/rules/evaluator.js
CHANGED
|
@@ -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":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,eAAe,EAAiB,MAAM,yBAAyB,CAAA;
|
|
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,
|
|
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"}
|