@rindle/client 0.1.0-rc.5
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/LICENSE +201 -0
- package/README.md +65 -0
- package/dist/ast.d.ts +83 -0
- package/dist/ast.d.ts.map +1 -0
- package/dist/ast.js +5 -0
- package/dist/ast.js.map +1 -0
- package/dist/compare.d.ts +17 -0
- package/dist/compare.d.ts.map +1 -0
- package/dist/compare.js +81 -0
- package/dist/compare.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/key.d.ts +2 -0
- package/dist/key.d.ts.map +1 -0
- package/dist/key.js +26 -0
- package/dist/key.js.map +1 -0
- package/dist/operators.d.ts +39 -0
- package/dist/operators.d.ts.map +1 -0
- package/dist/operators.js +45 -0
- package/dist/operators.js.map +1 -0
- package/dist/query.d.ts +280 -0
- package/dist/query.d.ts.map +1 -0
- package/dist/query.js +348 -0
- package/dist/query.js.map +1 -0
- package/dist/schema.d.ts +111 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +92 -0
- package/dist/schema.js.map +1 -0
- package/dist/ssr.d.ts +73 -0
- package/dist/ssr.d.ts.map +1 -0
- package/dist/ssr.js +66 -0
- package/dist/ssr.js.map +1 -0
- package/dist/store.d.ts +90 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +225 -0
- package/dist/store.js.map +1 -0
- package/dist/types.d.ts +250 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +20 -0
- package/dist/types.js.map +1 -0
- package/dist/view.d.ts +88 -0
- package/dist/view.d.ts.map +1 -0
- package/dist/view.js +294 -0
- package/dist/view.js.map +1 -0
- package/package.json +36 -0
- package/src/ast.ts +94 -0
- package/src/compare.ts +85 -0
- package/src/index.ts +57 -0
- package/src/key.ts +23 -0
- package/src/operators.ts +68 -0
- package/src/query.ts +734 -0
- package/src/schema.ts +181 -0
- package/src/ssr.ts +115 -0
- package/src/store.ts +279 -0
- package/src/types.ts +234 -0
- package/src/view.ts +348 -0
package/dist/ssr.d.ts
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import type { Query } from "./query.ts";
|
|
2
|
+
import type { ColsMap, Schema } from "./schema.ts";
|
|
3
|
+
import { type AssembledNode, type DehydratedState, Store } from "./store.ts";
|
|
4
|
+
import type { Backend, ChangeEvent, Mutation, QueryId, RemoteQuery } from "./types.ts";
|
|
5
|
+
/** A `POST /query` response, as far as the server Store needs it (SSR-DESIGN.md §3.3): the
|
|
6
|
+
* assembled rows plus the `cvMin` baseline they reflect. (Matches `@rindle/daemon-client`'s
|
|
7
|
+
* `QueryOnceOutput`, but `@rindle/client` stays dependency-free — inject the call.) */
|
|
8
|
+
export interface OneShotResult {
|
|
9
|
+
rows: AssembledNode[];
|
|
10
|
+
cvMin?: number;
|
|
11
|
+
}
|
|
12
|
+
/** The one-shot read the server Store calls to preload a query. Two topologies inject different
|
|
13
|
+
* fns (SSR-DESIGN.md §6):
|
|
14
|
+
*
|
|
15
|
+
* - **Direct to the daemon** (the trusted tier holds the daemon token): use `ast` —
|
|
16
|
+
* `(i) => daemon.query(i)`.
|
|
17
|
+
* - **Through the application's API tier** (the authority resolves names → ASTs, the loader never
|
|
18
|
+
* sends a raw AST): use `name`/`args` — `(i) => fetch('/api/rindle/read', {name: i.name, args: i.args})`.
|
|
19
|
+
*
|
|
20
|
+
* `ast` is always present (the Store seeds the local view by its `viewKey`); `name`/`args` are
|
|
21
|
+
* present when the preloaded query came from `defineQuery`. The Store applies no policy/auth —
|
|
22
|
+
* that lives upstream (the daemon, or the API tier's `authorizeQuery`). */
|
|
23
|
+
export type OneShotQueryFn = (input: {
|
|
24
|
+
ast: unknown;
|
|
25
|
+
name?: string;
|
|
26
|
+
args?: unknown;
|
|
27
|
+
visibilityKey?: string;
|
|
28
|
+
ttlMs?: number;
|
|
29
|
+
}) => Promise<OneShotResult>;
|
|
30
|
+
/**
|
|
31
|
+
* A no-op live backend for SSR (SSR-DESIGN.md §6.1): it opens no transport and never streams.
|
|
32
|
+
* `registerQuery`/`mutate` are inert and no `ChangeEvent` is ever pushed, so every view stays
|
|
33
|
+
* PENDING — reading its SSR {@link Store.seedAssembled seed} — and, lacking `onResultType`,
|
|
34
|
+
* reports `complete` (a backend with no server lifecycle leaves every view authoritative).
|
|
35
|
+
*/
|
|
36
|
+
export declare class OneShotBackend implements Backend {
|
|
37
|
+
registerQuery(_qid: QueryId, _ast: unknown, _remote?: RemoteQuery): void;
|
|
38
|
+
unregisterQuery(_qid: QueryId): void;
|
|
39
|
+
mutate(_mutations: Mutation[]): Promise<void>;
|
|
40
|
+
onEvent(_handler: (queryId: QueryId, event: ChangeEvent) => void): void;
|
|
41
|
+
}
|
|
42
|
+
export interface ServerStoreOptions {
|
|
43
|
+
/** Performs the one-shot `POST /query` read (e.g. a `@rindle/daemon-client` instance's `query`). */
|
|
44
|
+
query: OneShotQueryFn;
|
|
45
|
+
/** Optional RLS/visibility dedup key forwarded to every preload (SSR-DESIGN.md §3.2). The daemon
|
|
46
|
+
* scopes the materialization's dedup `QueryKey` by it, so the same AST under two visibility keys
|
|
47
|
+
* never shares one pipeline; absent ⇒ the daemon's configured default. */
|
|
48
|
+
visibilityKey?: string;
|
|
49
|
+
/** Optional idle TTL (ms) the warm pipeline is left at, forwarded to every preload (SSR-DESIGN.md
|
|
50
|
+
* §3.4). The TTL is NOT part of the dedup key, so a shared materialization keeps the LONGEST TTL
|
|
51
|
+
* any caller requested (max-wins) — `ttlMs` can extend a query's warm-handoff window, never
|
|
52
|
+
* shrink it; absent ⇒ the daemon's default idle TTL. */
|
|
53
|
+
ttlMs?: number;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* The server-side Store wrapper (SSR-DESIGN.md §6.2). Wraps a {@link Store} over a
|
|
57
|
+
* {@link OneShotBackend} and adds the loader-phase `preload` plus `dehydrate`. Pass `.store` to
|
|
58
|
+
* the React `<Rindle>` provider for the synchronous render; return `.dehydrate()` from the loader.
|
|
59
|
+
*/
|
|
60
|
+
export declare class ServerStore<S extends ColsMap> {
|
|
61
|
+
readonly store: Store<S>;
|
|
62
|
+
private readonly opts;
|
|
63
|
+
constructor(schema: Schema<S>, opts: ServerStoreOptions);
|
|
64
|
+
/** Run the one-shot read for `query` and seed its first-paint snapshot (SSR-DESIGN.md §6.2).
|
|
65
|
+
* Call once per query in the route loader, before the synchronous render. */
|
|
66
|
+
preload(query: Query<any, any, any>): Promise<void>;
|
|
67
|
+
/** The dehydrated first-paint cache for every preloaded query — embed in the HTML, then
|
|
68
|
+
* `store.hydrate(...)` it in the browser. */
|
|
69
|
+
dehydrate(): DehydratedState;
|
|
70
|
+
}
|
|
71
|
+
/** Construct a {@link ServerStore} — the one-shot REST Store for server-side rendering. */
|
|
72
|
+
export declare function createServerStore<S extends ColsMap>(schema: Schema<S>, opts: ServerStoreOptions): ServerStore<S>;
|
|
73
|
+
//# sourceMappingURL=ssr.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ssr.d.ts","sourceRoot":"","sources":["../src/ssr.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,KAAK,aAAa,EAAE,KAAK,eAAe,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAC7E,OAAO,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEvF;;wFAEwF;AACxF,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,aAAa,EAAE,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;;4EAU4E;AAC5E,MAAM,MAAM,cAAc,GAAG,CAC3B,KAAK,EAAE;IAAE,GAAG,EAAE,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,KAC3F,OAAO,CAAC,aAAa,CAAC,CAAC;AAE5B;;;;;GAKG;AACH,qBAAa,cAAe,YAAW,OAAO;IAC5C,aAAa,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,IAAI;IACxE,eAAe,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI;IACpC,MAAM,CAAC,UAAU,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAG7C,OAAO,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,WAAW,KAAK,IAAI,GAAG,IAAI;CACxE;AAED,MAAM,WAAW,kBAAkB;IACjC,oGAAoG;IACpG,KAAK,EAAE,cAAc,CAAC;IACtB;;+EAE2E;IAC3E,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;6DAGyD;IACzD,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,qBAAa,WAAW,CAAC,CAAC,SAAS,OAAO;IACxC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;IACzB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAqB;gBAE9B,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,kBAAkB;IAKvD;kFAC8E;IACxE,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBzD;kDAC8C;IAC9C,SAAS,IAAI,eAAe;CAG7B;AAED,2FAA2F;AAC3F,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,OAAO,EACjD,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,EACjB,IAAI,EAAE,kBAAkB,GACvB,WAAW,CAAC,CAAC,CAAC,CAEhB"}
|
package/dist/ssr.js
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
// SSR client integration (SSR-DESIGN.md §6). Server-side render is synchronous, so the data
|
|
2
|
+
// must already be in the cache when the render reads it. The seam is the BACKEND, not the hook:
|
|
3
|
+
//
|
|
4
|
+
// - Browser: the normal ws-backed Store — retain → lease → subscribe → live.
|
|
5
|
+
// - Server : a Store over a one-shot REST backend ({@link OneShotBackend}) that never streams.
|
|
6
|
+
// The route loader `preload`s each query (`POST /query`), which seeds the view for an
|
|
7
|
+
// instant correct first paint; `dehydrate` serializes those seeds into the HTML; the
|
|
8
|
+
// browser `store.hydrate(...)`s them and its live `subscribe` reconciles (§5).
|
|
9
|
+
//
|
|
10
|
+
// `useQuery` is byte-for-byte identical in both — only the injected backend (and whether a live
|
|
11
|
+
// subscribe ever happens) differs.
|
|
12
|
+
import { Store } from "./store.js";
|
|
13
|
+
/**
|
|
14
|
+
* A no-op live backend for SSR (SSR-DESIGN.md §6.1): it opens no transport and never streams.
|
|
15
|
+
* `registerQuery`/`mutate` are inert and no `ChangeEvent` is ever pushed, so every view stays
|
|
16
|
+
* PENDING — reading its SSR {@link Store.seedAssembled seed} — and, lacking `onResultType`,
|
|
17
|
+
* reports `complete` (a backend with no server lifecycle leaves every view authoritative).
|
|
18
|
+
*/
|
|
19
|
+
export class OneShotBackend {
|
|
20
|
+
registerQuery(_qid, _ast, _remote) { }
|
|
21
|
+
unregisterQuery(_qid) { }
|
|
22
|
+
mutate(_mutations) {
|
|
23
|
+
return Promise.reject(new Error("the SSR one-shot backend is read-only; mutate on the browser store"));
|
|
24
|
+
}
|
|
25
|
+
onEvent(_handler) { }
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* The server-side Store wrapper (SSR-DESIGN.md §6.2). Wraps a {@link Store} over a
|
|
29
|
+
* {@link OneShotBackend} and adds the loader-phase `preload` plus `dehydrate`. Pass `.store` to
|
|
30
|
+
* the React `<Rindle>` provider for the synchronous render; return `.dehydrate()` from the loader.
|
|
31
|
+
*/
|
|
32
|
+
export class ServerStore {
|
|
33
|
+
store;
|
|
34
|
+
opts;
|
|
35
|
+
constructor(schema, opts) {
|
|
36
|
+
this.store = new Store(schema, new OneShotBackend());
|
|
37
|
+
this.opts = opts;
|
|
38
|
+
}
|
|
39
|
+
/** Run the one-shot read for `query` and seed its first-paint snapshot (SSR-DESIGN.md §6.2).
|
|
40
|
+
* Call once per query in the route loader, before the synchronous render. */
|
|
41
|
+
async preload(query) {
|
|
42
|
+
const ast = query.ast();
|
|
43
|
+
// Forward the AST (a direct-to-daemon backend reads it) plus the named identity when this came
|
|
44
|
+
// from `defineQuery` (an API-tier backend resolves `(name, args)` → AST itself, never trusting
|
|
45
|
+
// a client AST). The seed is keyed by the AST's `viewKey` either way, so the browser's
|
|
46
|
+
// `getServerSnapshot` finds it (SSR-DESIGN.md §6.2).
|
|
47
|
+
const named = typeof query.name === "string" ? { name: query.name, args: query.args } : undefined;
|
|
48
|
+
const result = await this.opts.query({
|
|
49
|
+
ast,
|
|
50
|
+
...named,
|
|
51
|
+
visibilityKey: this.opts.visibilityKey,
|
|
52
|
+
ttlMs: this.opts.ttlMs,
|
|
53
|
+
});
|
|
54
|
+
this.store.seedAssembled(ast, result.rows, result.cvMin ?? 0);
|
|
55
|
+
}
|
|
56
|
+
/** The dehydrated first-paint cache for every preloaded query — embed in the HTML, then
|
|
57
|
+
* `store.hydrate(...)` it in the browser. */
|
|
58
|
+
dehydrate() {
|
|
59
|
+
return this.store.dehydrate();
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/** Construct a {@link ServerStore} — the one-shot REST Store for server-side rendering. */
|
|
63
|
+
export function createServerStore(schema, opts) {
|
|
64
|
+
return new ServerStore(schema, opts);
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=ssr.js.map
|
package/dist/ssr.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ssr.js","sourceRoot":"","sources":["../src/ssr.ts"],"names":[],"mappings":"AAAA,4FAA4F;AAC5F,gGAAgG;AAChG,EAAE;AACF,+EAA+E;AAC/E,iGAAiG;AACjG,mGAAmG;AACnG,kGAAkG;AAClG,4FAA4F;AAC5F,EAAE;AACF,gGAAgG;AAChG,mCAAmC;AAInC,OAAO,EAA4C,KAAK,EAAE,MAAM,YAAY,CAAC;AA0B7E;;;;;GAKG;AACH,MAAM,OAAO,cAAc;IACzB,aAAa,CAAC,IAAa,EAAE,IAAa,EAAE,OAAqB,IAAS,CAAC;IAC3E,eAAe,CAAC,IAAa,IAAS,CAAC;IACvC,MAAM,CAAC,UAAsB;QAC3B,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,oEAAoE,CAAC,CAAC,CAAC;IACzG,CAAC;IACD,OAAO,CAAC,QAAwD,IAAS,CAAC;CAC3E;AAgBD;;;;GAIG;AACH,MAAM,OAAO,WAAW;IACb,KAAK,CAAW;IACR,IAAI,CAAqB;IAE1C,YAAY,MAAiB,EAAE,IAAwB;QACrD,IAAI,CAAC,KAAK,GAAG,IAAI,KAAK,CAAC,MAAM,EAAE,IAAI,cAAc,EAAE,CAAC,CAAC;QACrD,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;IAED;kFAC8E;IAC9E,KAAK,CAAC,OAAO,CAAC,KAA2B;QACvC,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,EAAE,CAAC;QACxB,+FAA+F;QAC/F,+FAA+F;QAC/F,uFAAuF;QACvF,qDAAqD;QACrD,MAAM,KAAK,GAAG,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;QAClG,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;YACnC,GAAG;YACH,GAAG,KAAK;YACR,aAAa,EAAE,IAAI,CAAC,IAAI,CAAC,aAAa;YACtC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK;SACvB,CAAC,CAAC;QACH,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC;IAChE,CAAC;IAED;kDAC8C;IAC9C,SAAS;QACP,OAAO,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC;IAChC,CAAC;CACF;AAED,2FAA2F;AAC3F,MAAM,UAAU,iBAAiB,CAC/B,MAAiB,EACjB,IAAwB;IAExB,OAAO,IAAI,WAAW,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;AACvC,CAAC"}
|
package/dist/store.d.ts
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import type { Ast } from "./ast.ts";
|
|
2
|
+
import { type Query, type QueryRoot } from "./query.ts";
|
|
3
|
+
import type { ColsMap, RowOf, Schema } from "./schema.ts";
|
|
4
|
+
import type { Backend, WireValue } from "./types.ts";
|
|
5
|
+
/** One query's SSR snapshot, keyed by its `viewKey` ({@link stableKey} of the AST): the
|
|
6
|
+
* pre-projected first-paint `rows` plus the `cvMin` watermark they reflect (SSR-DESIGN.md §6.2).
|
|
7
|
+
* Serializable as-is into the HTML — `rows` are already JSON values (json columns parsed). */
|
|
8
|
+
export interface DehydratedQuery {
|
|
9
|
+
rows: unknown[];
|
|
10
|
+
cvMin: number;
|
|
11
|
+
}
|
|
12
|
+
/** The whole dehydrated cache: every preloaded query's snapshot, keyed by `viewKey`. The server
|
|
13
|
+
* builds it with {@link Store.dehydrate}; the browser seeds it with {@link Store.hydrate}. */
|
|
14
|
+
export type DehydratedState = Record<string, DehydratedQuery>;
|
|
15
|
+
/** A single assembled (nested-by-name) row from `POST /query` (SSR-DESIGN.md §3.3): the cells
|
|
16
|
+
* under `cols`, each in-view relationship inlined by its alias (a nested array / object, or a
|
|
17
|
+
* scalar for a `countAs` aggregate). {@link Store.assembleSnapshot} converts these to the
|
|
18
|
+
* view's projected result shape. */
|
|
19
|
+
export interface AssembledNode {
|
|
20
|
+
cols: Record<string, WireValue>;
|
|
21
|
+
[rel: string]: unknown;
|
|
22
|
+
}
|
|
23
|
+
/** The write transaction handed to `store.write(tx => …)`. Rows are objects keyed by column;
|
|
24
|
+
* the Store positionalizes them (and stringifies json columns) before the backend sees them. */
|
|
25
|
+
export interface WriteTx<S extends ColsMap> {
|
|
26
|
+
add<N extends keyof S & string>(table: N, row: RowOf<S[N]>): void;
|
|
27
|
+
remove<N extends keyof S & string>(table: N, row: RowOf<S[N]>): void;
|
|
28
|
+
edit<N extends keyof S & string>(table: N, oldRow: RowOf<S[N]>, newRow: RowOf<S[N]>): void;
|
|
29
|
+
}
|
|
30
|
+
export interface CachedQueryView<Q extends Query<any, any, any>> {
|
|
31
|
+
readonly view: ReturnType<Q["materialize"]>;
|
|
32
|
+
/** Retain this query's named remote footprint and release it later. Ad-hoc local queries
|
|
33
|
+
* return a no-op release function. */
|
|
34
|
+
retain(query: Q): () => void;
|
|
35
|
+
destroy(): void;
|
|
36
|
+
}
|
|
37
|
+
export declare class Store<S extends ColsMap> {
|
|
38
|
+
/** Type-safe query entry: `store.query.issue.where.closed(false).materialize()`. */
|
|
39
|
+
readonly query: QueryRoot<S>;
|
|
40
|
+
private readonly schema;
|
|
41
|
+
private readonly backend;
|
|
42
|
+
private nextId;
|
|
43
|
+
private readonly views;
|
|
44
|
+
private readonly asts;
|
|
45
|
+
private readonly seeds;
|
|
46
|
+
constructor(schema: Schema<S>, backend: Backend);
|
|
47
|
+
/** Materialize any fluent query object. Named queries subscribe remotely by `(name,args)`;
|
|
48
|
+
* ad-hoc builder queries are local-only for local-first backends. */
|
|
49
|
+
materialize<Q extends Query<any, any, any>>(query: Q): ReturnType<Q["materialize"]>;
|
|
50
|
+
/** True when the backend can retain a remote named query independently from the local
|
|
51
|
+
* materialized AST view. React uses this to keep one local view per AST while still sending
|
|
52
|
+
* every mounted `(name,args)` lease through the backend. */
|
|
53
|
+
canRetainRemoteQueries(): boolean;
|
|
54
|
+
/** Build one local AST view, with remote syncing retained separately through the returned
|
|
55
|
+
* handle. This is a lower-level API for UI bindings; ordinary app code should keep using
|
|
56
|
+
* `materialize(query)`. */
|
|
57
|
+
createCachedQueryView<Q extends Query<any, any, any>>(query: Q): CachedQueryView<Q>;
|
|
58
|
+
/** Apply a batch of mutations (object rows → positional). Resolves when the backend has
|
|
59
|
+
* accepted them (local: applied; remote: sent). The resulting view updates flow back via
|
|
60
|
+
* the backend's event stream. */
|
|
61
|
+
write(fn: (tx: WriteTx<S>) => void): Promise<void>;
|
|
62
|
+
/** Seed a query's first-paint snapshot from a `POST /query` response (server side): convert the
|
|
63
|
+
* assembled rows to the view's projected shape and stash them by `viewKey`. A view materialized
|
|
64
|
+
* for this AST (during the synchronous render) reads the seed; {@link dehydrate} serializes it. */
|
|
65
|
+
seedAssembled(ast: Ast, rows: AssembledNode[], cvMin: number): void;
|
|
66
|
+
/** The dehydrated first-paint cache for every preloaded query — embed it in the HTML and pass it
|
|
67
|
+
* to {@link hydrate} in the browser (SSR-DESIGN.md §6.2). */
|
|
68
|
+
dehydrate(): DehydratedState;
|
|
69
|
+
/** Seed the browser store from the server's {@link dehydrate} output (SSR-DESIGN.md §6.2): each
|
|
70
|
+
* view materialized for a hydrated AST shows these rows until its first live `hello` reconciles. */
|
|
71
|
+
hydrate(state: DehydratedState): void;
|
|
72
|
+
/** A query's hydrated first-paint snapshot, by `viewKey` — what React's `getServerSnapshot`
|
|
73
|
+
* reads so an SSR render (and the matching client hydration pass) sees the seeded rows without
|
|
74
|
+
* opening a subscription. */
|
|
75
|
+
seedSnapshot(viewKey: string): DehydratedQuery | undefined;
|
|
76
|
+
/** Convert assembled (nested-by-name) rows (SSR-DESIGN.md §3.3) into the view's projected result
|
|
77
|
+
* shape: spread `cols` (parsing json columns), recurse into each relationship by its alias
|
|
78
|
+
* (plural → array, `.one()` → object/null, `countAs` → bare scalar). */
|
|
79
|
+
assembleSnapshot(ast: Ast, rows: AssembledNode[]): unknown[];
|
|
80
|
+
private assembleNode;
|
|
81
|
+
private registerMaterialized;
|
|
82
|
+
private retainRemote;
|
|
83
|
+
private onEvent;
|
|
84
|
+
private columns;
|
|
85
|
+
/** An object row → a positional cell array in the table's column order (json → string). */
|
|
86
|
+
private positionalize;
|
|
87
|
+
/** The per-level column types parallel to the WireSchema, so the view parses json columns. */
|
|
88
|
+
private viewTypes;
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAEpC,OAAO,EAAW,KAAK,KAAK,EAAE,KAAK,SAAS,EAAE,MAAM,YAAY,CAAC;AACjE,OAAO,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC1D,OAAO,KAAK,EAAE,OAAO,EAAoE,SAAS,EAAE,MAAM,YAAY,CAAC;AAGvH;;+FAE+F;AAC/F,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,OAAO,EAAE,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf;AAED;+FAC+F;AAC/F,MAAM,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;AAE9D;;;qCAGqC;AACrC,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAChC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED;iGACiG;AACjG,MAAM,WAAW,OAAO,CAAC,CAAC,SAAS,OAAO;IACxC,GAAG,CAAC,CAAC,SAAS,MAAM,CAAC,GAAG,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IAClE,MAAM,CAAC,CAAC,SAAS,MAAM,CAAC,GAAG,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IACrE,IAAI,CAAC,CAAC,SAAS,MAAM,CAAC,GAAG,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;CAC5F;AAED,MAAM,WAAW,eAAe,CAAC,CAAC,SAAS,KAAK,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IAC7D,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC;IAC5C;2CACuC;IACvC,MAAM,CAAC,KAAK,EAAE,CAAC,GAAG,MAAM,IAAI,CAAC;IAC7B,OAAO,IAAI,IAAI,CAAC;CACjB;AAED,qBAAa,KAAK,CAAC,CAAC,SAAS,OAAO;IAClC,oFAAoF;IACpF,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;IAE7B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAY;IACnC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAU;IAClC,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAqC;IAC3D,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA2B;IAIhD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAsC;gBAEhD,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO;IAU/C;0EACsE;IACtE,WAAW,CAAC,CAAC,SAAS,KAAK,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC;IAKnF;;iEAE6D;IAC7D,sBAAsB,IAAI,OAAO;IAOjC;;gCAE4B;IAC5B,qBAAqB,CAAC,CAAC,SAAS,KAAK,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC;IAcnF;;sCAEkC;IAClC,KAAK,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBlD;;wGAEoG;IACpG,aAAa,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,aAAa,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAInE;kEAC8D;IAC9D,SAAS,IAAI,eAAe;IAI5B;yGACqG;IACrG,OAAO,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI;IAIrC;;kCAE8B;IAC9B,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS;IAI1D;;6EAEyE;IACzE,gBAAgB,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,aAAa,EAAE,GAAG,OAAO,EAAE;IAI5D,OAAO,CAAC,YAAY;IAuBpB,OAAO,CAAC,oBAAoB;IAiC5B,OAAO,CAAC,YAAY;IAapB,OAAO,CAAC,OAAO;IAkBf,OAAO,CAAC,OAAO;IAMf,2FAA2F;IAC3F,OAAO,CAAC,aAAa;IASrB,8FAA8F;IAC9F,OAAO,CAAC,SAAS;CAWlB"}
|
package/dist/store.js
ADDED
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
// The Store — backend-agnostic glue (WASM-CLIENT-DESIGN.md §2). Holds the typed schema +
|
|
2
|
+
// a `Backend`, exposes `store.query.<table>…materialize()` and `store.write(tx => …)`, and
|
|
3
|
+
// routes the backend's per-query `ChangeEvent` stream into per-query `ArrayView`s.
|
|
4
|
+
//
|
|
5
|
+
// It never knows whether the backend is the in-process WASM engine or a remote server —
|
|
6
|
+
// both speak `registerQuery` / `mutate` / `onEvent`. The Store owns: query-id assignment,
|
|
7
|
+
// building each `ArrayView` (typed from the schema, so json columns parse), dispatching
|
|
8
|
+
// hello/snapshot/batch events, and turning object-shaped writes into positional mutations.
|
|
9
|
+
import { stableKey } from "./key.js";
|
|
10
|
+
import { queries } from "./query.js";
|
|
11
|
+
import { FlatArrayView, SingularView } from "./view.js";
|
|
12
|
+
export class Store {
|
|
13
|
+
/** Type-safe query entry: `store.query.issue.where.closed(false).materialize()`. */
|
|
14
|
+
query;
|
|
15
|
+
schema;
|
|
16
|
+
backend;
|
|
17
|
+
nextId = 1;
|
|
18
|
+
views = new Map();
|
|
19
|
+
asts = new Map();
|
|
20
|
+
// SSR seeds (SSR-DESIGN.md §6), keyed by `viewKey`: a view materialized for one of these is
|
|
21
|
+
// seeded for first paint; a seed is consumed (dropped) the moment its query's first live
|
|
22
|
+
// `hello` lands, so later mounts don't flash stale SSR data.
|
|
23
|
+
seeds = new Map();
|
|
24
|
+
constructor(schema, backend) {
|
|
25
|
+
this.schema = schema;
|
|
26
|
+
this.backend = backend;
|
|
27
|
+
this.backend.onEvent((qid, ev) => this.onEvent(qid, ev));
|
|
28
|
+
// Route the backend's per-query lifecycle onto its view (`view.resultType`). Backends without a
|
|
29
|
+
// lifecycle omit `onResultType`, leaving every view `complete`.
|
|
30
|
+
this.backend.onResultType?.((qid, rt) => this.views.get(qid)?.setResultType(rt));
|
|
31
|
+
this.query = queries(this.schema, (query) => this.materialize(query));
|
|
32
|
+
}
|
|
33
|
+
/** Materialize any fluent query object. Named queries subscribe remotely by `(name,args)`;
|
|
34
|
+
* ad-hoc builder queries are local-only for local-first backends. */
|
|
35
|
+
materialize(query) {
|
|
36
|
+
const remote = typeof query.name === "string" ? { name: query.name, args: query.args } : undefined;
|
|
37
|
+
return this.registerMaterialized(query.ast(), remote).view;
|
|
38
|
+
}
|
|
39
|
+
/** True when the backend can retain a remote named query independently from the local
|
|
40
|
+
* materialized AST view. React uses this to keep one local view per AST while still sending
|
|
41
|
+
* every mounted `(name,args)` lease through the backend. */
|
|
42
|
+
canRetainRemoteQueries() {
|
|
43
|
+
return (typeof this.backend.retainRemoteQuery === "function" &&
|
|
44
|
+
typeof this.backend.releaseRemoteQuery === "function");
|
|
45
|
+
}
|
|
46
|
+
/** Build one local AST view, with remote syncing retained separately through the returned
|
|
47
|
+
* handle. This is a lower-level API for UI bindings; ordinary app code should keep using
|
|
48
|
+
* `materialize(query)`. */
|
|
49
|
+
createCachedQueryView(query) {
|
|
50
|
+
const { qid, view } = this.registerMaterialized(query.ast(), undefined);
|
|
51
|
+
let destroyed = false;
|
|
52
|
+
return {
|
|
53
|
+
view: view,
|
|
54
|
+
retain: (nextQuery) => this.retainRemote(nextQuery, qid),
|
|
55
|
+
destroy: () => {
|
|
56
|
+
if (destroyed)
|
|
57
|
+
return;
|
|
58
|
+
destroyed = true;
|
|
59
|
+
view.destroy();
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
/** Apply a batch of mutations (object rows → positional). Resolves when the backend has
|
|
64
|
+
* accepted them (local: applied; remote: sent). The resulting view updates flow back via
|
|
65
|
+
* the backend's event stream. */
|
|
66
|
+
write(fn) {
|
|
67
|
+
const muts = [];
|
|
68
|
+
const tx = {
|
|
69
|
+
add: (t, row) => muts.push({ op: "add", table: t, row: this.positionalize(t, row) }),
|
|
70
|
+
remove: (t, row) => muts.push({ op: "remove", table: t, row: this.positionalize(t, row) }),
|
|
71
|
+
edit: (t, o, n) => muts.push({ op: "edit", table: t, old: this.positionalize(t, o), new: this.positionalize(t, n) }),
|
|
72
|
+
};
|
|
73
|
+
fn(tx);
|
|
74
|
+
return Promise.resolve(this.backend.mutate(muts));
|
|
75
|
+
}
|
|
76
|
+
// --- SSR (SSR-DESIGN.md §6) ---------------------------------------------------
|
|
77
|
+
/** Seed a query's first-paint snapshot from a `POST /query` response (server side): convert the
|
|
78
|
+
* assembled rows to the view's projected shape and stash them by `viewKey`. A view materialized
|
|
79
|
+
* for this AST (during the synchronous render) reads the seed; {@link dehydrate} serializes it. */
|
|
80
|
+
seedAssembled(ast, rows, cvMin) {
|
|
81
|
+
this.seeds.set(stableKey(ast), { rows: this.assembleSnapshot(ast, rows), cvMin });
|
|
82
|
+
}
|
|
83
|
+
/** The dehydrated first-paint cache for every preloaded query — embed it in the HTML and pass it
|
|
84
|
+
* to {@link hydrate} in the browser (SSR-DESIGN.md §6.2). */
|
|
85
|
+
dehydrate() {
|
|
86
|
+
return Object.fromEntries(this.seeds);
|
|
87
|
+
}
|
|
88
|
+
/** Seed the browser store from the server's {@link dehydrate} output (SSR-DESIGN.md §6.2): each
|
|
89
|
+
* view materialized for a hydrated AST shows these rows until its first live `hello` reconciles. */
|
|
90
|
+
hydrate(state) {
|
|
91
|
+
for (const [key, snap] of Object.entries(state))
|
|
92
|
+
this.seeds.set(key, snap);
|
|
93
|
+
}
|
|
94
|
+
/** A query's hydrated first-paint snapshot, by `viewKey` — what React's `getServerSnapshot`
|
|
95
|
+
* reads so an SSR render (and the matching client hydration pass) sees the seeded rows without
|
|
96
|
+
* opening a subscription. */
|
|
97
|
+
seedSnapshot(viewKey) {
|
|
98
|
+
return this.seeds.get(viewKey);
|
|
99
|
+
}
|
|
100
|
+
/** Convert assembled (nested-by-name) rows (SSR-DESIGN.md §3.3) into the view's projected result
|
|
101
|
+
* shape: spread `cols` (parsing json columns), recurse into each relationship by its alias
|
|
102
|
+
* (plural → array, `.one()` → object/null, `countAs` → bare scalar). */
|
|
103
|
+
assembleSnapshot(ast, rows) {
|
|
104
|
+
return rows.map((row) => this.assembleNode(ast, row));
|
|
105
|
+
}
|
|
106
|
+
assembleNode(ast, node) {
|
|
107
|
+
const cols = this.columns(ast.table);
|
|
108
|
+
const out = {};
|
|
109
|
+
for (const [name, v] of Object.entries(node.cols ?? {})) {
|
|
110
|
+
out[name] = cols[name]?.type === "json" && typeof v === "string" ? JSON.parse(v) : v;
|
|
111
|
+
}
|
|
112
|
+
for (const sub of ast.related ?? []) {
|
|
113
|
+
const alias = sub.subquery.alias;
|
|
114
|
+
if (alias === undefined || !(alias in node))
|
|
115
|
+
continue;
|
|
116
|
+
const child = node[alias];
|
|
117
|
+
if (Array.isArray(child)) {
|
|
118
|
+
out[alias] = child.map((c) => this.assembleNode(sub.subquery, c));
|
|
119
|
+
}
|
|
120
|
+
else if (child !== null && typeof child === "object") {
|
|
121
|
+
out[alias] = this.assembleNode(sub.subquery, child); // .one() singular
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
out[alias] = child; // a `countAs` scalar aggregate, or a null singular relationship
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return out;
|
|
128
|
+
}
|
|
129
|
+
// --- internals ---------------------------------------------------------------
|
|
130
|
+
registerMaterialized(ast, remote) {
|
|
131
|
+
const qid = this.nextId++;
|
|
132
|
+
this.asts.set(qid, ast);
|
|
133
|
+
// Pre-create the view (PENDING) so `materialize` is synchronous for ANY backend — a remote
|
|
134
|
+
// backend's `hello` arrives async (the view reads as `[]` until then). A synchronous backend
|
|
135
|
+
// (wasm/replica) resets it during `registerQuery` below, so it returns already-hydrated.
|
|
136
|
+
const view = this.views.get(qid) ?? this.views.set(qid, new FlatArrayView()).get(qid);
|
|
137
|
+
// Wire teardown: `destroy()` must unregister the query from the backend and drop our routing
|
|
138
|
+
// entry. Otherwise the engine keeps emitting events for the destroyed query and the Store
|
|
139
|
+
// routes them to the now-empty view — which throws on the next Child/remove ("parent not
|
|
140
|
+
// found") and, because dispatch is a single loop, aborts delivery to sibling queries too.
|
|
141
|
+
// This bites whenever a query is re-materialized (e.g. a changed limit/filter rebuilds it).
|
|
142
|
+
const baseDestroy = view.destroy.bind(view);
|
|
143
|
+
view.destroy = () => {
|
|
144
|
+
if (this.views.delete(qid)) {
|
|
145
|
+
this.asts.delete(qid);
|
|
146
|
+
this.backend.unregisterQuery(qid);
|
|
147
|
+
}
|
|
148
|
+
baseDestroy();
|
|
149
|
+
};
|
|
150
|
+
this.backend.registerQuery(qid, ast, remote);
|
|
151
|
+
// SSR first paint (SSR-DESIGN.md §6): if this AST was preloaded/hydrated, seed the view now.
|
|
152
|
+
// A synchronous backend (wasm) already reset the view above, so its live data wins and the
|
|
153
|
+
// seed is inert; an async backend (ws) leaves it PENDING, so the seed shows until `hello`.
|
|
154
|
+
const seed = this.seeds.get(stableKey(ast));
|
|
155
|
+
if (seed)
|
|
156
|
+
view.seed(seed.rows);
|
|
157
|
+
// A top-level `.one()` (engine-capped to limit 1) unwraps at the result boundary.
|
|
158
|
+
return { qid, view: ast.one ? new SingularView(view) : view };
|
|
159
|
+
}
|
|
160
|
+
retainRemote(query, localQueryId) {
|
|
161
|
+
const remote = typeof query.name === "string" ? { name: query.name, args: query.args } : undefined;
|
|
162
|
+
if (!remote || !this.canRetainRemoteQueries())
|
|
163
|
+
return () => { };
|
|
164
|
+
const qid = this.nextId++;
|
|
165
|
+
this.backend.retainRemoteQuery?.(qid, remote, localQueryId);
|
|
166
|
+
let released = false;
|
|
167
|
+
return () => {
|
|
168
|
+
if (released)
|
|
169
|
+
return;
|
|
170
|
+
released = true;
|
|
171
|
+
this.backend.releaseRemoteQuery?.(qid);
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
onEvent(qid, ev) {
|
|
175
|
+
if (ev.type === "hello") {
|
|
176
|
+
const ast = this.asts.get(qid);
|
|
177
|
+
// First live hello for this view ⇒ retire its SSR seed: the maintained tree now owns the
|
|
178
|
+
// result, so no future mount of the same query should flash the stale first-paint rows.
|
|
179
|
+
if (ast)
|
|
180
|
+
this.seeds.delete(stableKey(ast));
|
|
181
|
+
const types = ast ? this.viewTypes(ev.schema, ast) : undefined;
|
|
182
|
+
// Reset the (pre-created or existing) view IN PLACE — first hello OR a re-hydrate (new
|
|
183
|
+
// epoch) — so the materialized reference the caller holds survives a re-subscribe.
|
|
184
|
+
const view = this.views.get(qid) ?? this.views.set(qid, new FlatArrayView()).get(qid);
|
|
185
|
+
view.reset(ev.schema, types);
|
|
186
|
+
}
|
|
187
|
+
else if (ev.type === "snapshot") {
|
|
188
|
+
this.views.get(qid)?.applyChanges(ev.adds);
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
this.views.get(qid)?.applyChanges(ev.events);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
columns(table) {
|
|
195
|
+
const meta = this.schema.tables[table];
|
|
196
|
+
if (!meta)
|
|
197
|
+
throw new Error(`unknown table: ${table}`);
|
|
198
|
+
return meta.columns;
|
|
199
|
+
}
|
|
200
|
+
/** An object row → a positional cell array in the table's column order (json → string). */
|
|
201
|
+
positionalize(table, obj) {
|
|
202
|
+
const cols = this.columns(table);
|
|
203
|
+
return Object.keys(cols).map((name) => {
|
|
204
|
+
const v = obj[name];
|
|
205
|
+
if (cols[name].type === "json" && v != null && typeof v === "object")
|
|
206
|
+
return JSON.stringify(v);
|
|
207
|
+
return (v ?? null);
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
/** The per-level column types parallel to the WireSchema, so the view parses json columns. */
|
|
211
|
+
viewTypes(ws, ast) {
|
|
212
|
+
const cols = this.columns(ast.table);
|
|
213
|
+
const columnTypes = ws.columns.map((name) => cols[name]?.type ?? "string");
|
|
214
|
+
const rels = {};
|
|
215
|
+
for (const rel of ws.relationships) {
|
|
216
|
+
if (!rel.child)
|
|
217
|
+
continue;
|
|
218
|
+
const sub = (ast.related ?? []).find((r) => r.subquery.alias === rel.name);
|
|
219
|
+
if (sub)
|
|
220
|
+
rels[rel.slot] = this.viewTypes(rel.child, sub.subquery);
|
|
221
|
+
}
|
|
222
|
+
return { columnTypes, rels };
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
//# sourceMappingURL=store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"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"}
|