@jarenjs/linq 0.49.2 → 0.66.1
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/ARCHITECTURE.md +227 -0
- package/README.md +650 -17
- package/docs/APP-PEN.md +1143 -0
- package/docs/CONTRACT-PEN.md +1221 -0
- package/docs/DB-CLIENT.md +882 -0
- package/docs/FLOW-PEN.md +1033 -0
- package/docs/FORMS-PEN.md +940 -0
- package/docs/JSLT-PEN.md +955 -0
- package/docs/LINQ-FORMAT.md +778 -383
- package/docs/MIGRATION-PEN.md +781 -0
- package/docs/MODEL-PEN.md +1092 -0
- package/docs/QUERY-PEN.md +1724 -0
- package/docs/SCHEMA-PEN.md +1218 -0
- package/package.json +57 -4
- package/src/app/action.js +251 -0
- package/src/app/capture.js +63 -0
- package/src/app/define.js +255 -0
- package/src/app/index.js +20 -0
- package/src/app/patch.js +277 -0
- package/src/app/sub.js +106 -0
- package/src/async.js +377 -75
- package/src/capture-root.js +82 -0
- package/src/concurrency.js +48 -11
- package/src/contract/define.js +282 -0
- package/src/contract/http.js +247 -0
- package/src/contract/index.js +23 -0
- package/src/contract/operation.js +338 -0
- package/src/db/handle.js +89 -0
- package/src/db/include.js +351 -0
- package/src/db/index.js +24 -0
- package/src/db/ledger.js +195 -0
- package/src/db/live.js +43 -0
- package/src/db/membership.js +37 -0
- package/src/db/open.js +130 -0
- package/src/document.js +143 -13
- package/src/effect.js +65 -0
- package/src/errors.js +78 -6
- package/src/expression.js +463 -36
- package/src/federate.js +531 -0
- package/src/flow/capture.js +33 -0
- package/src/flow/dag.js +316 -0
- package/src/flow/fsm.js +323 -0
- package/src/flow/index.js +22 -0
- package/src/forms/index.js +43 -0
- package/src/forms/rules.js +170 -0
- package/src/forms/submit.js +177 -0
- package/src/index.js +5 -2
- package/src/jslt/body.js +226 -0
- package/src/jslt/index.js +18 -0
- package/src/jslt/rules.js +202 -0
- package/src/json-boundary.js +90 -0
- package/src/migration/define.js +318 -0
- package/src/migration/index.js +15 -0
- package/src/migration/steps.js +244 -0
- package/src/model/collection.js +273 -0
- package/src/model/define.js +125 -0
- package/src/model/entity.js +307 -0
- package/src/model/index.js +47 -0
- package/src/model/relation.js +85 -0
- package/src/provider.js +137 -20
- package/src/schema/brand.js +31 -0
- package/src/schema/builders.js +526 -0
- package/src/schema/check.js +29 -0
- package/src/schema/emit.js +394 -0
- package/src/schema/factories.js +239 -0
- package/src/schema/index.js +37 -0
- package/src/schema-of.js +24 -0
- package/src/sequence.js +233 -103
- package/src/sources.js +10 -3
- package/types/app.d.ts +293 -0
- package/types/contract.d.ts +468 -0
- package/types/db.d.ts +359 -0
- package/types/flow.d.ts +285 -0
- package/types/forms.d.ts +253 -0
- package/types/index.d.ts +296 -26
- package/types/jslt.d.ts +193 -0
- package/types/migration.d.ts +201 -0
- package/types/model.d.ts +526 -0
- package/types/schema.d.ts +494 -0
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hand-authored declarations for `@jarenjs/linq/migration` — the
|
|
3
|
+
* migration pen's type contract, on the line every pen keeps: the common
|
|
4
|
+
* path precisely typed, the exotic path honestly `unknown`, nothing ever
|
|
5
|
+
* a WRONG type.
|
|
6
|
+
*
|
|
7
|
+
* A transform is typed from the two model documents' phantoms. `from`
|
|
8
|
+
* gives the OLD shape of the named table (`InferMeta<typeof
|
|
9
|
+
* previous>[name]['doc']`), the value the callback is captured over;
|
|
10
|
+
* `to` gives the NEW shape, which the callback's result must SPELL — a
|
|
11
|
+
* member forgotten, mistyped or not in the new shape is a compile error,
|
|
12
|
+
* and the honest top (`UnknownExpr`, a `get()`) is admitted wherever a
|
|
13
|
+
* precise value is, because the runtime validator is the judge there.
|
|
14
|
+
* From a JSON snapshot the old shape is `unknown` and the value the
|
|
15
|
+
* honest top; the author annotates it (`(u: Expr<User>) => …`) from the
|
|
16
|
+
* declaration `jaren-db snapshot --types` writes, or keeps the previous
|
|
17
|
+
* model module beside the current one so the phantom is there. An
|
|
18
|
+
* assertion's row is typed by the members the two shapes SHARE (a
|
|
19
|
+
* precondition sees old rows, a postcondition new ones; what both agree
|
|
20
|
+
* on is what neither lies about), annotated when one shape is meant.
|
|
21
|
+
* Every claim here has a runtime twin in
|
|
22
|
+
* `test/linq/migration-pen.test.js` and a compile-level pin in
|
|
23
|
+
* `test/consumer/linq-migration.ts`.
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
import type { BoolExpr, DateTime, ExprBase, MemberExpr, UnknownExpr } from './index.js';
|
|
27
|
+
import type { Json } from './schema.js';
|
|
28
|
+
import type { ModelDocument, InferMeta } from './model.js';
|
|
29
|
+
import type { Externals, RuleDocument, RuleOut, ValueOf } from './jslt.js';
|
|
30
|
+
|
|
31
|
+
// ————— the document —————
|
|
32
|
+
|
|
33
|
+
export interface DdlStep { readonly kind: 'ddl'; readonly sql: string; readonly note?: string }
|
|
34
|
+
export interface SqlStep { readonly kind: 'sql'; readonly sql: string; readonly note?: string }
|
|
35
|
+
export interface JsltStep {
|
|
36
|
+
readonly kind: 'jslt';
|
|
37
|
+
readonly collection: string;
|
|
38
|
+
readonly stylesheet: readonly RuleDocument[];
|
|
39
|
+
/** A planner placeholder; the runner refuses it (`JD0021`). The pen never sets or clears it. */
|
|
40
|
+
readonly draft?: boolean;
|
|
41
|
+
readonly note?: string;
|
|
42
|
+
}
|
|
43
|
+
export interface QueryStep {
|
|
44
|
+
readonly kind: 'query';
|
|
45
|
+
readonly collection: string;
|
|
46
|
+
readonly assert: Json;
|
|
47
|
+
readonly expect?: 'empty' | 'ebv';
|
|
48
|
+
readonly note?: string;
|
|
49
|
+
}
|
|
50
|
+
export interface DeriveColumn {
|
|
51
|
+
readonly name: string;
|
|
52
|
+
readonly derive: 'geohash' | 'bbox' | 'vector';
|
|
53
|
+
readonly precision?: number;
|
|
54
|
+
readonly dims?: number;
|
|
55
|
+
readonly component?: 'w' | 's' | 'e' | 'n';
|
|
56
|
+
readonly segments: readonly object[];
|
|
57
|
+
}
|
|
58
|
+
export interface DeriveStep {
|
|
59
|
+
readonly kind: 'derive';
|
|
60
|
+
readonly collection: string;
|
|
61
|
+
readonly columns: readonly DeriveColumn[];
|
|
62
|
+
readonly note?: string;
|
|
63
|
+
}
|
|
64
|
+
export interface RebuildStep {
|
|
65
|
+
readonly kind: 'rebuild';
|
|
66
|
+
readonly table: string;
|
|
67
|
+
readonly create: readonly string[];
|
|
68
|
+
readonly copy: string;
|
|
69
|
+
readonly indexes: readonly string[];
|
|
70
|
+
readonly note?: string;
|
|
71
|
+
}
|
|
72
|
+
export type MigrationStep = DdlStep | SqlStep | JsltStep | QueryStep | DeriveStep | RebuildStep;
|
|
73
|
+
|
|
74
|
+
/** The `$migration` 0.1 document (MIGRATION-FORMAT §2). */
|
|
75
|
+
export interface MigrationDocument {
|
|
76
|
+
readonly $migration: '0.1';
|
|
77
|
+
readonly id: string;
|
|
78
|
+
readonly from: string;
|
|
79
|
+
readonly to: string;
|
|
80
|
+
readonly note?: string;
|
|
81
|
+
readonly steps: readonly MigrationStep[];
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// ————— what a model document types —————
|
|
85
|
+
|
|
86
|
+
/** The entities and collections a model document declares; any string
|
|
87
|
+
* for a document the type cannot read (a JSON snapshot). */
|
|
88
|
+
export type DeclaredNames<M> = M extends ModelDocument<infer E, infer C>
|
|
89
|
+
? (unknown extends E ? string : keyof E & string) | (unknown extends C ? string : keyof C & string)
|
|
90
|
+
: string;
|
|
91
|
+
|
|
92
|
+
/** The document shape of table `N` in a model — an entity's `doc`; the
|
|
93
|
+
* honest `unknown` for a collection, a JSON snapshot, or a name the
|
|
94
|
+
* model does not type. */
|
|
95
|
+
export type DocOf<M, N extends string> =
|
|
96
|
+
[InferMeta<M>] extends [never] ? unknown
|
|
97
|
+
: N extends keyof InferMeta<M>
|
|
98
|
+
? (InferMeta<M>[N] extends { doc: infer D } ? D : unknown)
|
|
99
|
+
: unknown;
|
|
100
|
+
|
|
101
|
+
/** How a value of `T` is spelled in a transform's result: the value
|
|
102
|
+
* itself, an expression yielding it, the honest top, or — for an object
|
|
103
|
+
* — a literal spelling each member the same way; `unknown` admits
|
|
104
|
+
* anything. */
|
|
105
|
+
export type Spell<T> = SpellPresent<Exclude<T, undefined>> | (undefined extends T ? undefined : never);
|
|
106
|
+
type SpellPresent<T> =
|
|
107
|
+
unknown extends T ? unknown :
|
|
108
|
+
[T] extends [DateTime] ? string | ExprBase<string> | UnknownExpr :
|
|
109
|
+
[T] extends [readonly (infer E)[]] ? T | ExprBase<T> | UnknownExpr | readonly Spell<E>[] :
|
|
110
|
+
[T] extends [object] ? T | ExprBase<T> | UnknownExpr | { readonly [K in keyof T]: Spell<T[K]> } :
|
|
111
|
+
T | ExprBase<T> | UnknownExpr;
|
|
112
|
+
|
|
113
|
+
/** A rules array's verdict: a typed first rule must produce the new
|
|
114
|
+
* shape; a hand-written rule (`unknown` out) is the honest top. */
|
|
115
|
+
export type RulesFor<R extends readonly RuleDocument[], New> =
|
|
116
|
+
unknown extends RuleOut<R[0]> ? unknown : RuleOut<R[0]> extends New ? unknown : never;
|
|
117
|
+
|
|
118
|
+
/** Any stylesheet envelope: the JSLT pen's (phantoms and all) or a hand-written one. */
|
|
119
|
+
export type StylesheetLike = { readonly $jslt: '0.1'; readonly rules: readonly RuleDocument[] };
|
|
120
|
+
|
|
121
|
+
/** A stylesheet's verdict: a typed one must produce the new shape; an
|
|
122
|
+
* untyped or hand-written one is the honest top. */
|
|
123
|
+
export type SheetFor<S, New> = S extends { readonly __out: infer O }
|
|
124
|
+
? (unknown extends O ? unknown : O extends New ? unknown : never)
|
|
125
|
+
: unknown;
|
|
126
|
+
|
|
127
|
+
export interface AssertOptions {
|
|
128
|
+
/** `'empty'` (the default, absent from the document): no row may
|
|
129
|
+
* satisfy the predicate — it names the violation; `'ebv'`: the matching
|
|
130
|
+
* rows are the witness. */
|
|
131
|
+
readonly expect?: 'empty' | 'ebv';
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// ————— the builder —————
|
|
135
|
+
|
|
136
|
+
/** The migration under construction: immutable, every method a new
|
|
137
|
+
* builder; `.document`/`toJSON()` the deep-frozen document. */
|
|
138
|
+
export class Migration<From = unknown, To = unknown> {
|
|
139
|
+
private constructor();
|
|
140
|
+
/** One rendered DDL statement (`ddl`). */
|
|
141
|
+
ddl(sql: string, note?: string): Migration<From, To>;
|
|
142
|
+
/** One data statement spelled directly (`sql`, MIGRATION-FORMAT §9.4). */
|
|
143
|
+
sql(sql: string, note?: string): Migration<From, To>;
|
|
144
|
+
/** A `jslt` step: one root rule captured over the OLD row (`root`/`path`
|
|
145
|
+
* as externals), whose result spells the NEW row. Over a planned
|
|
146
|
+
* document it replaces the draft for `name`; otherwise it is appended
|
|
147
|
+
* for a table the target declares. */
|
|
148
|
+
transform<N extends DeclaredNames<To>, V extends ExprBase<unknown> = MemberExpr<DocOf<From, N>>>(
|
|
149
|
+
name: N,
|
|
150
|
+
rule: (row: V, x: Externals<{}, ValueOf<V>>) => Spell<DocOf<To, N>>,
|
|
151
|
+
): Migration<From, To>;
|
|
152
|
+
/** A `stylesheet(…)` document — its output must be the new row when it
|
|
153
|
+
* is typed; a hand-written envelope is the honest top. A disposition or
|
|
154
|
+
* a mode table cannot ride in a `jslt` step (`JL0102`). */
|
|
155
|
+
transform<N extends DeclaredNames<To>, S extends StylesheetLike>(
|
|
156
|
+
name: N,
|
|
157
|
+
stylesheet: S & SheetFor<S, DocOf<To, N>>,
|
|
158
|
+
): Migration<From, To>;
|
|
159
|
+
/** A rules array: a typed first rule must produce the new row; a
|
|
160
|
+
* hand-written rule is the honest top. */
|
|
161
|
+
transform<N extends DeclaredNames<To>, const R extends readonly RuleDocument[]>(
|
|
162
|
+
name: N,
|
|
163
|
+
rules: R & RulesFor<R, DocOf<To, N>>,
|
|
164
|
+
): Migration<From, To>;
|
|
165
|
+
/** A `query` step over `name`'s rows: the predicate names the VIOLATION
|
|
166
|
+
* (`expect: 'empty'`, the default) or the witness (`'ebv'`); the row is
|
|
167
|
+
* the members the two shapes share, annotated when one shape is meant. */
|
|
168
|
+
assert<N extends DeclaredNames<To>, V extends ExprBase<unknown> = MemberExpr<DocOf<From, N> | DocOf<To, N>>>(
|
|
169
|
+
name: N,
|
|
170
|
+
predicate: (row: V) => BoolExpr | boolean,
|
|
171
|
+
options?: AssertOptions,
|
|
172
|
+
): Migration<From, To>;
|
|
173
|
+
/** A query document over the rows, verbatim. */
|
|
174
|
+
assert<N extends DeclaredNames<To>>(name: N, query: Json, options?: AssertOptions): Migration<From, To>;
|
|
175
|
+
/** A backfill of stored derived columns (`derive`, §2.1). */
|
|
176
|
+
derive<N extends DeclaredNames<To>>(name: N, columns: readonly DeriveColumn[]): Migration<From, To>;
|
|
177
|
+
/** Any planner-emitted step, verbatim — the escape that keeps `rebuild` authorable. */
|
|
178
|
+
step(raw: MigrationStep): Migration<From, To>;
|
|
179
|
+
readonly document: MigrationDocument;
|
|
180
|
+
toJSON(): MigrationDocument;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
export interface MigrationSpec<From, To> {
|
|
184
|
+
readonly id: string;
|
|
185
|
+
/** The model the store is at: a model document (the pen's or a JSON snapshot). */
|
|
186
|
+
readonly from: From;
|
|
187
|
+
/** The model the code carries. */
|
|
188
|
+
readonly to: To;
|
|
189
|
+
readonly note?: string;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/** A migration between two model documents; `from`/`to` are their shape hashes. */
|
|
193
|
+
export function defineMigration<From extends object, To extends object>(spec: MigrationSpec<From, To>): Migration<From, To>;
|
|
194
|
+
|
|
195
|
+
/** A planner's document, taken up so a typed `transform` replaces the
|
|
196
|
+
* draft it left; `from`/`to` type the transforms and are checked against
|
|
197
|
+
* the document's hashes (`JL0102` when they are not the planned models). */
|
|
198
|
+
export function fromPlanned<From = unknown, To = unknown>(
|
|
199
|
+
document: MigrationDocument | Json,
|
|
200
|
+
options?: { readonly from?: From; readonly to?: To },
|
|
201
|
+
): Migration<From, To>;
|