@jarenjs/db 0.56.0 → 0.67.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/ARCHITECTURE.md +412 -56
- package/README.md +600 -57
- package/docs/HOSTS.md +269 -0
- package/docs/JOBS-FORMAT.md +293 -45
- package/docs/LIVE-FORMAT.md +169 -20
- package/docs/MIGRATION-FORMAT.md +142 -17
- package/docs/MODEL-FORMAT.md +752 -64
- package/docs/REPLICATION-FORMAT.md +208 -0
- package/package.json +21 -7
- package/schemas/jaren-model.draft-07.schema.json +224 -162
- package/schemas/jaren-model.schema.json +224 -162
- package/schemas/jaren-replication-snapshot.draft-07.schema.json +83 -0
- package/schemas/jaren-replication-snapshot.schema.json +83 -0
- package/schemas/jaren-replication.draft-07.schema.json +82 -0
- package/schemas/jaren-replication.schema.json +82 -0
- package/src/algebra.js +227 -9
- package/src/backup.js +161 -0
- package/src/cancellation.js +48 -0
- package/src/capture.js +230 -47
- package/src/cli.js +165 -59
- package/src/cursor.js +417 -0
- package/src/dag-job.js +154 -21
- package/src/ddl.js +102 -8
- package/src/dialect.js +268 -113
- package/src/dialects/expression-read.js +158 -0
- package/src/dialects/postgres.js +618 -0
- package/src/dialects/rtree-ddl.js +129 -0
- package/src/dialects/sqlite.js +244 -11
- package/src/document-files.js +311 -0
- package/src/document-steps.js +422 -0
- package/src/documents.js +335 -0
- package/src/driver.js +448 -61
- package/src/drivers/bun.js +37 -1
- package/src/drivers/indexeddb-snapshot.js +149 -0
- package/src/drivers/node-pool.js +11 -0
- package/src/drivers/node-worker-endpoint.js +105 -0
- package/src/drivers/node-worker.js +204 -0
- package/src/drivers/node.js +41 -7
- package/src/drivers/postgres.js +331 -0
- package/src/drivers/wasm-oo1.js +97 -0
- package/src/drivers/wasm-session.js +67 -0
- package/src/drivers/wasm.js +17 -83
- package/src/drivers/worker-pool.js +183 -0
- package/src/drivers/worker-protocol.js +79 -0
- package/src/drivers/worker-queue.js +60 -0
- package/src/emit.js +339 -48
- package/src/entity.js +20 -22
- package/src/errors.js +430 -19
- package/src/expression.js +284 -0
- package/src/graph.js +64 -8
- package/src/index.js +48 -17
- package/src/introspect.js +583 -0
- package/src/jobs.js +843 -107
- package/src/json-bytes.js +58 -0
- package/src/live-join.js +250 -0
- package/src/live-nested.js +120 -0
- package/src/live.js +18 -4
- package/src/logical-rows.js +90 -0
- package/src/maintenance.js +175 -0
- package/src/migrate.js +248 -181
- package/src/model.js +68 -0
- package/src/plan.js +1119 -138
- package/src/pragmas.js +314 -0
- package/src/profile.js +151 -3
- package/src/query.js +1634 -323
- package/src/replication-format.js +115 -0
- package/src/replication.js +332 -0
- package/src/residual.js +17 -0
- package/src/series.js +12 -4
- package/src/store.js +1567 -273
- package/src/tracker.js +203 -29
- package/src/udf.js +88 -7
- package/types/index.d.ts +1158 -27
- package/types/node-pool.d.ts +28 -0
- package/types/node-worker.d.ts +54 -0
- package/types/node.d.ts +69 -2
- package/types/postgres.d.ts +46 -0
- package/types/typed.d.ts +27 -4
- package/types/wasm.d.ts +14 -0
|
@@ -1,176 +1,238 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
},
|
|
12
|
-
"collections": {
|
|
13
|
-
"description": "Collection name (an identifier) to collection declaration.",
|
|
14
|
-
"type": "object",
|
|
15
|
-
"minProperties": 1,
|
|
16
|
-
"propertyNames": {
|
|
17
|
-
"pattern": "^[A-Za-z_][A-Za-z0-9_]*$"
|
|
18
|
-
},
|
|
19
|
-
"additionalProperties": {
|
|
20
|
-
"$ref": "#/definitions/collection"
|
|
21
|
-
}
|
|
22
|
-
},
|
|
23
|
-
"entities": {
|
|
24
|
-
"description": "Entity name (an identifier) to entity declaration. The x-entity vocabulary lives INSIDE each entity schema's property subschemas and is documented in MODEL-FORMAT.md §9; stripping it leaves a plain JSON Schema.",
|
|
25
|
-
"type": "object",
|
|
26
|
-
"minProperties": 1,
|
|
27
|
-
"propertyNames": {
|
|
28
|
-
"pattern": "^[A-Za-z_][A-Za-z0-9_]*$"
|
|
29
|
-
},
|
|
30
|
-
"additionalProperties": {
|
|
31
|
-
"$ref": "#/definitions/entity"
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
},
|
|
35
|
-
"required": [
|
|
36
|
-
"$model"
|
|
37
|
-
],
|
|
38
|
-
"additionalProperties": false,
|
|
39
|
-
"definitions": {
|
|
40
|
-
"collection": {
|
|
41
|
-
"description": "One collection: a document schema, the key declaration, and the declared indexes. A collection without a key pointer MUST declare how keys are allocated; allocation is declared, never guessed.",
|
|
42
|
-
"type": "object",
|
|
43
|
-
"properties": {
|
|
44
|
-
"schema": {
|
|
45
|
-
"description": "The JSON Schema every stored document validates against (through the injected hook). Also the type source for indexed paths.",
|
|
46
|
-
"type": "object"
|
|
47
|
-
},
|
|
48
|
-
"key": {
|
|
49
|
-
"description": "Where the caller-supplied key lives in the document, as an RFC 6901 pointer selecting at least one member — or null when the store allocates.",
|
|
50
|
-
"type": [
|
|
51
|
-
"string",
|
|
52
|
-
"null"
|
|
53
|
-
],
|
|
54
|
-
"pattern": "^/"
|
|
55
|
-
},
|
|
56
|
-
"identity": {
|
|
57
|
-
"description": "How keys come to be: 'caller' (the default when a key pointer is declared), or — only with \"key\": null — 'uuid' (crypto.randomUUID) or 'integer' (database-allocated).",
|
|
58
|
-
"enum": [
|
|
59
|
-
"caller",
|
|
60
|
-
"uuid",
|
|
61
|
-
"integer"
|
|
62
|
-
]
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"$id": "https://jarenjs.dev/schemas/jaren-model/draft-07",
|
|
4
|
+
"title": "Jaren model document",
|
|
5
|
+
"description": "A jaren-model document declares the collections of a store: each collection is a JSON Schema for its documents, a key declaration (an RFC 6901 pointer for caller-supplied keys, or null with a declared identity for store-allocated ones), and the indexes over singular JSONPath expressions. A model declares collections (the storage subset: every property JSONB, no relations), entities (the relational subset: keys, typed columns, relations via the x-entity vocabulary), or both; vocabulary is added to THIS format, never as a second format.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"properties": {
|
|
8
|
+
"$model": {
|
|
9
|
+
"description": "The model format version.",
|
|
10
|
+
"const": "0.1"
|
|
63
11
|
},
|
|
64
|
-
"
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
"
|
|
69
|
-
|
|
12
|
+
"collections": {
|
|
13
|
+
"description": "Collection name (an identifier) to collection declaration.",
|
|
14
|
+
"type": "object",
|
|
15
|
+
"minProperties": 1,
|
|
16
|
+
"propertyNames": {
|
|
17
|
+
"pattern": "^[A-Za-z_][A-Za-z0-9_]*$"
|
|
18
|
+
},
|
|
19
|
+
"additionalProperties": {
|
|
20
|
+
"$ref": "#/definitions/collection"
|
|
21
|
+
}
|
|
70
22
|
},
|
|
71
|
-
"
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
23
|
+
"entities": {
|
|
24
|
+
"description": "Entity name (an identifier) to entity declaration. The x-entity vocabulary lives INSIDE each entity schema's property subschemas and is documented in MODEL-FORMAT.md \u00a79; stripping it leaves a plain JSON Schema.",
|
|
25
|
+
"type": "object",
|
|
26
|
+
"minProperties": 1,
|
|
27
|
+
"propertyNames": {
|
|
28
|
+
"pattern": "^[A-Za-z_][A-Za-z0-9_]*$"
|
|
29
|
+
},
|
|
30
|
+
"additionalProperties": {
|
|
31
|
+
"$ref": "#/definitions/entity"
|
|
32
|
+
}
|
|
75
33
|
}
|
|
76
|
-
},
|
|
77
|
-
"required": [
|
|
78
|
-
"schema"
|
|
79
|
-
],
|
|
80
|
-
"additionalProperties": false
|
|
81
34
|
},
|
|
82
|
-
"
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
35
|
+
"required": [
|
|
36
|
+
"$model"
|
|
37
|
+
],
|
|
38
|
+
"additionalProperties": false,
|
|
39
|
+
"definitions": {
|
|
40
|
+
"collection": {
|
|
41
|
+
"description": "One collection: a document schema, the key declaration, and the declared indexes. A collection without a key pointer MUST declare how keys are allocated; allocation is declared, never guessed.",
|
|
42
|
+
"type": "object",
|
|
43
|
+
"properties": {
|
|
44
|
+
"schema": {
|
|
45
|
+
"description": "The JSON Schema every stored document validates against (through the injected hook). Also the type source for indexed paths.",
|
|
46
|
+
"type": "object"
|
|
47
|
+
},
|
|
48
|
+
"key": {
|
|
49
|
+
"description": "Where the caller-supplied key lives in the document, as an RFC 6901 pointer selecting at least one member \u2014 or null when the store allocates.",
|
|
50
|
+
"type": [
|
|
51
|
+
"string",
|
|
52
|
+
"null"
|
|
53
|
+
],
|
|
54
|
+
"pattern": "^/"
|
|
55
|
+
},
|
|
56
|
+
"identity": {
|
|
57
|
+
"description": "How keys come to be: 'caller' (the default when a key pointer is declared), or \u2014 only with \"key\": null \u2014 'uuid' (crypto.randomUUID) or 'integer' (database-allocated).",
|
|
58
|
+
"enum": [
|
|
59
|
+
"caller",
|
|
60
|
+
"uuid",
|
|
61
|
+
"integer"
|
|
62
|
+
]
|
|
63
|
+
},
|
|
64
|
+
"indexes": {
|
|
65
|
+
"description": "Declared indexes; each singular path becomes a generated column plus an index.",
|
|
66
|
+
"type": "array",
|
|
67
|
+
"items": {
|
|
68
|
+
"$ref": "#/definitions/index"
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
"x-rename": {
|
|
72
|
+
"description": "Migration hint: this collection was previously named the given identifier. Read by the migration planner (a rename cannot be inferred from a diff); ignored by the store.",
|
|
73
|
+
"type": "string",
|
|
74
|
+
"pattern": "^[A-Za-z_][A-Za-z0-9_]*$"
|
|
75
|
+
}
|
|
97
76
|
},
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
"minLength": 1
|
|
103
|
-
},
|
|
104
|
-
"minItems": 1
|
|
105
|
-
}
|
|
106
|
-
]
|
|
107
|
-
},
|
|
108
|
-
"unique": {
|
|
109
|
-
"description": "Whether the index enforces uniqueness. Defaults to false.",
|
|
110
|
-
"type": "boolean"
|
|
111
|
-
},
|
|
112
|
-
"derive": {
|
|
113
|
-
"description": "Derive columns from the selected member instead of indexing it: 'geohash' (one TEXT cell column, precision required), 'bbox' (four REAL columns — west, south, east, north), or 'vector' (one packed BLOB column holding the l2-normalized Float32 form of an array of numbers, dims required; stored on every driver, with no B-tree over it — a fetch-and-rank plan reads it whole). A derived index is never unique.",
|
|
114
|
-
"enum": [
|
|
115
|
-
"geohash",
|
|
116
|
-
"bbox",
|
|
117
|
-
"vector"
|
|
118
|
-
]
|
|
77
|
+
"required": [
|
|
78
|
+
"schema"
|
|
79
|
+
],
|
|
80
|
+
"additionalProperties": false
|
|
119
81
|
},
|
|
120
|
-
"
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
82
|
+
"index": {
|
|
83
|
+
"description": "One index over a singular JSONPath expression (or a composite over several). A non-singular path is rejected at open (JD0004). A derived index computes indexable scalars from the selected member instead of indexing it directly. An index may instead declare an expression: a closed computation over members, scalars and host-declared deterministic functions.",
|
|
84
|
+
"type": "object",
|
|
85
|
+
"properties": {
|
|
86
|
+
"name": {
|
|
87
|
+
"description": "The index name, unique within its collection.",
|
|
88
|
+
"type": "string",
|
|
89
|
+
"pattern": "^[A-Za-z_][A-Za-z0-9_]*$"
|
|
90
|
+
},
|
|
91
|
+
"path": {
|
|
92
|
+
"description": "A singular JSONPath expression into the stored document ($.email), or a non-empty array of them for a composite index.",
|
|
93
|
+
"oneOf": [
|
|
94
|
+
{
|
|
95
|
+
"type": "string",
|
|
96
|
+
"minLength": 1
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
"type": "array",
|
|
100
|
+
"items": {
|
|
101
|
+
"type": "string",
|
|
102
|
+
"minLength": 1
|
|
103
|
+
},
|
|
104
|
+
"minItems": 1
|
|
105
|
+
}
|
|
106
|
+
]
|
|
107
|
+
},
|
|
108
|
+
"expression": {
|
|
109
|
+
"description": "Index a computed value rather than a member: a closed expression over declared members, JSON scalars and functions the host declared deterministic. Mutually exclusive with path and derive (JD0004) \u2014 an expression names the members it reads itself.",
|
|
110
|
+
"allOf": [
|
|
111
|
+
{
|
|
112
|
+
"$ref": "#/definitions/expression"
|
|
113
|
+
}
|
|
114
|
+
]
|
|
115
|
+
},
|
|
116
|
+
"unique": {
|
|
117
|
+
"description": "Whether the index enforces uniqueness. Defaults to false.",
|
|
118
|
+
"type": "boolean"
|
|
119
|
+
},
|
|
120
|
+
"derive": {
|
|
121
|
+
"description": "Derive columns from the selected member instead of indexing it: 'geohash' (one TEXT cell column, precision required), 'bbox' (four REAL columns \u2014 west, south, east, north), or 'vector' (one packed BLOB column holding the l2-normalized Float32 form of an array of numbers, dims required; stored on every driver, with no B-tree over it \u2014 a fetch-and-rank plan reads it whole). A derived index is never unique.",
|
|
122
|
+
"enum": [
|
|
123
|
+
"geohash",
|
|
124
|
+
"bbox",
|
|
125
|
+
"vector"
|
|
126
|
+
]
|
|
127
|
+
},
|
|
128
|
+
"precision": {
|
|
129
|
+
"description": "Geohash cell length in characters, 1-12. Required beside derive: 'geohash' and refused anywhere else \u2014 there is no safe default, because the right cell size depends on the query radius, which the model cannot know.",
|
|
130
|
+
"type": "integer",
|
|
131
|
+
"minimum": 1,
|
|
132
|
+
"maximum": 12
|
|
133
|
+
},
|
|
134
|
+
"dims": {
|
|
135
|
+
"description": "The width of a derive: 'vector' column in components, 1-8192. Required beside derive: 'vector' and refused anywhere else: the width is the column's identity \u2014 two widths over one path are two columns \u2014 and a member that is not an array of exactly this many finite numbers stores NULL in the column (the document itself still stores). Constrain the member with minItems/maxItems equal to dims in the collection's schema so a wrong-width vector is refused at the write instead.",
|
|
136
|
+
"type": "integer",
|
|
137
|
+
"minimum": 1,
|
|
138
|
+
"maximum": 8192
|
|
139
|
+
},
|
|
140
|
+
"physical": {
|
|
141
|
+
"description": "The shape a derive: 'bbox' index takes on disk: 'columns' (the default) is four generated columns under one B-tree; 'rtree' keeps the same four columns and adds a SQLite R*Tree virtual table beside the collection, kept in sync by declared triggers, with no B-tree over the columns. The logical meaning of derive: 'bbox' is identical either way. Refused on any other index kind, and on a driver without the module it falls back to 'columns' and says so through explain().prefilters[].via.",
|
|
142
|
+
"enum": [
|
|
143
|
+
"columns",
|
|
144
|
+
"rtree"
|
|
145
|
+
]
|
|
146
|
+
}
|
|
147
|
+
},
|
|
148
|
+
"required": [
|
|
149
|
+
"name"
|
|
150
|
+
],
|
|
151
|
+
"additionalProperties": false
|
|
125
152
|
},
|
|
126
|
-
"
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
153
|
+
"entity": {
|
|
154
|
+
"description": "One entity: an object schema whose top-level properties map to columns per the hybrid rule (scalars become typed columns, nested shapes stay JSONB); keys, indexes, defaults and relations are declared with x-entity inside the schema.",
|
|
155
|
+
"type": "object",
|
|
156
|
+
"properties": {
|
|
157
|
+
"schema": {
|
|
158
|
+
"type": "object"
|
|
159
|
+
},
|
|
160
|
+
"x-rename": {
|
|
161
|
+
"type": "string",
|
|
162
|
+
"description": "Declares this entity as the rename of the named from-model entity (MIGRATION-FORMAT \u00a79): a rename is declared, never inferred."
|
|
163
|
+
}
|
|
164
|
+
},
|
|
165
|
+
"required": [
|
|
166
|
+
"schema"
|
|
167
|
+
],
|
|
168
|
+
"additionalProperties": false
|
|
131
169
|
},
|
|
132
|
-
"
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
"
|
|
136
|
-
|
|
137
|
-
|
|
170
|
+
"expression": {
|
|
171
|
+
"description": "One node of an index expression: a member path, a JSON scalar, or a call to a function the host declared. Exactly one of the three, and nothing else \u2014 an index expression is never SQL text, and the function it names is resolved for arity and determinism at open (JD0004).",
|
|
172
|
+
"type": "object",
|
|
173
|
+
"oneOf": [
|
|
174
|
+
{
|
|
175
|
+
"required": [
|
|
176
|
+
"member"
|
|
177
|
+
],
|
|
178
|
+
"properties": {
|
|
179
|
+
"member": {
|
|
180
|
+
"description": "A singular JSONPath expression into the stored document ($.email).",
|
|
181
|
+
"type": "string",
|
|
182
|
+
"minLength": 1
|
|
183
|
+
}
|
|
184
|
+
},
|
|
185
|
+
"additionalProperties": false
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
"required": [
|
|
189
|
+
"value"
|
|
190
|
+
],
|
|
191
|
+
"properties": {
|
|
192
|
+
"value": {
|
|
193
|
+
"description": "A JSON scalar. A null or a compound has no place in an index expression.",
|
|
194
|
+
"type": [
|
|
195
|
+
"string",
|
|
196
|
+
"number",
|
|
197
|
+
"boolean"
|
|
198
|
+
]
|
|
199
|
+
}
|
|
200
|
+
},
|
|
201
|
+
"additionalProperties": false
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
"required": [
|
|
205
|
+
"call"
|
|
206
|
+
],
|
|
207
|
+
"properties": {
|
|
208
|
+
"call": {
|
|
209
|
+
"description": "The name of a function the host declared through openStore({ expressions }). The store refuses a name it was not given, a wrong arity, and one not declared deterministic \u2014 before any DDL.",
|
|
210
|
+
"type": "string",
|
|
211
|
+
"pattern": "^[A-Za-z_][A-Za-z0-9_]*$"
|
|
212
|
+
},
|
|
213
|
+
"args": {
|
|
214
|
+
"description": "The arguments, in order. Order is significant: sub(a, b) and sub(b, a) are different expressions and different columns.",
|
|
215
|
+
"type": "array",
|
|
216
|
+
"items": {
|
|
217
|
+
"$ref": "#/definitions/expression"
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
},
|
|
221
|
+
"additionalProperties": false
|
|
222
|
+
}
|
|
223
|
+
]
|
|
138
224
|
}
|
|
139
|
-
},
|
|
140
|
-
"required": [
|
|
141
|
-
"name",
|
|
142
|
-
"path"
|
|
143
|
-
],
|
|
144
|
-
"additionalProperties": false
|
|
145
225
|
},
|
|
146
|
-
"
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
"type": "object"
|
|
226
|
+
"anyOf": [
|
|
227
|
+
{
|
|
228
|
+
"required": [
|
|
229
|
+
"collections"
|
|
230
|
+
]
|
|
152
231
|
},
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
232
|
+
{
|
|
233
|
+
"required": [
|
|
234
|
+
"entities"
|
|
235
|
+
]
|
|
156
236
|
}
|
|
157
|
-
|
|
158
|
-
"required": [
|
|
159
|
-
"schema"
|
|
160
|
-
],
|
|
161
|
-
"additionalProperties": false
|
|
162
|
-
}
|
|
163
|
-
},
|
|
164
|
-
"anyOf": [
|
|
165
|
-
{
|
|
166
|
-
"required": [
|
|
167
|
-
"collections"
|
|
168
|
-
]
|
|
169
|
-
},
|
|
170
|
-
{
|
|
171
|
-
"required": [
|
|
172
|
-
"entities"
|
|
173
|
-
]
|
|
174
|
-
}
|
|
175
|
-
]
|
|
237
|
+
]
|
|
176
238
|
}
|