js-bao 0.5.1 → 0.6.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/README.md +128 -30
- package/dist/browser.cjs +4759 -719
- package/dist/browser.d.cts +2290 -50
- package/dist/browser.d.ts +2290 -50
- package/dist/browser.js +4766 -722
- package/dist/client.cjs +383 -6
- package/dist/client.d.cts +810 -12
- package/dist/client.d.ts +810 -12
- package/dist/client.js +378 -4
- package/dist/cloudflare-do.cjs +1307 -219
- package/dist/cloudflare-do.d.cts +1195 -13
- package/dist/cloudflare-do.d.ts +1195 -13
- package/dist/cloudflare-do.js +1303 -217
- package/dist/cloudflare.cjs +619 -23
- package/dist/cloudflare.d.cts +1026 -13
- package/dist/cloudflare.d.ts +1026 -13
- package/dist/cloudflare.js +614 -21
- package/dist/codegen-v2.cjs +393 -19
- package/dist/codegen.cjs +2 -1
- package/dist/index.cjs +4830 -679
- package/dist/index.d.cts +2343 -52
- package/dist/index.d.ts +2343 -52
- package/dist/index.js +4746 -650
- package/dist/node.cjs +5016 -724
- package/dist/node.d.cts +2458 -58
- package/dist/node.d.ts +2458 -58
- package/dist/node.js +4906 -676
- package/package.json +2 -1
package/dist/cloudflare.cjs
CHANGED
|
@@ -100,6 +100,201 @@ var init_yjsValues = __esm({
|
|
|
100
100
|
}
|
|
101
101
|
});
|
|
102
102
|
|
|
103
|
+
// src/models/writeLifecycle.ts
|
|
104
|
+
function assertNever(x) {
|
|
105
|
+
throw new Error(`Unhandled field type: ${String(x)}`);
|
|
106
|
+
}
|
|
107
|
+
function fieldWriteKind(type) {
|
|
108
|
+
switch (type) {
|
|
109
|
+
case "string":
|
|
110
|
+
case "number":
|
|
111
|
+
case "boolean":
|
|
112
|
+
case "date":
|
|
113
|
+
case "id":
|
|
114
|
+
return "scalar";
|
|
115
|
+
case "stringset":
|
|
116
|
+
return "stringset";
|
|
117
|
+
default:
|
|
118
|
+
return assertNever(type);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
function isKnownFieldType(type) {
|
|
122
|
+
return KNOWN_FIELD_TYPES.has(type);
|
|
123
|
+
}
|
|
124
|
+
function ensureStringSetYMap(rm, fieldName) {
|
|
125
|
+
const nested = rm.get(fieldName);
|
|
126
|
+
if (nested instanceof Y2.Map) return nested;
|
|
127
|
+
const fresh = new Y2.Map();
|
|
128
|
+
if (nested && typeof nested === "object") {
|
|
129
|
+
for (const [member, marker] of Object.entries(
|
|
130
|
+
nested
|
|
131
|
+
)) {
|
|
132
|
+
if (Boolean(marker)) fresh.set(member, true);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
rm.set(fieldName, fresh);
|
|
136
|
+
return fresh;
|
|
137
|
+
}
|
|
138
|
+
function applyStringSetDelta(target, delta) {
|
|
139
|
+
if (delta.clear) {
|
|
140
|
+
for (const member of Array.from(target.keys())) target.delete(member);
|
|
141
|
+
}
|
|
142
|
+
if (delta.remove) {
|
|
143
|
+
for (const member of delta.remove) target.delete(String(member));
|
|
144
|
+
}
|
|
145
|
+
if (delta.add) {
|
|
146
|
+
for (const member of delta.add) {
|
|
147
|
+
const key = String(member);
|
|
148
|
+
if (target.get(key) !== true) target.set(key, true);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
function replaceStringSet(rm, fieldName, members) {
|
|
153
|
+
const target = ensureStringSetYMap(rm, fieldName);
|
|
154
|
+
const desired = /* @__PURE__ */ new Set();
|
|
155
|
+
for (const member of members) desired.add(String(member));
|
|
156
|
+
for (const existing of Array.from(target.keys())) {
|
|
157
|
+
if (!desired.has(existing)) target.delete(existing);
|
|
158
|
+
}
|
|
159
|
+
for (const member of desired) {
|
|
160
|
+
if (target.get(member) !== true) target.set(member, true);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
function applyStringSetChange(recordYMap, fieldName, change) {
|
|
164
|
+
const target = ensureStringSetYMap(recordYMap, fieldName);
|
|
165
|
+
applyStringSetDelta(target, {
|
|
166
|
+
add: change.additions,
|
|
167
|
+
remove: change.removals
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
function parseStringSetOp(value) {
|
|
171
|
+
if (value === null || typeof value !== "object" || Array.isArray(value) || value instanceof Y2.AbstractType) {
|
|
172
|
+
return null;
|
|
173
|
+
}
|
|
174
|
+
const keys = Object.keys(value);
|
|
175
|
+
const opKeys = keys.filter((k) => k.startsWith("$"));
|
|
176
|
+
if (opKeys.length === 0) return null;
|
|
177
|
+
const known = /* @__PURE__ */ new Set(["$add", "$remove", "$clear"]);
|
|
178
|
+
const unknown = keys.filter((k) => !known.has(k));
|
|
179
|
+
if (unknown.length > 0) {
|
|
180
|
+
throw new Error(
|
|
181
|
+
`Invalid stringset op: unexpected key(s) [${unknown.join(", ")}]. Only $add, $remove and $clear are supported.`
|
|
182
|
+
);
|
|
183
|
+
}
|
|
184
|
+
const obj = value;
|
|
185
|
+
const toMembers = (raw, opName) => {
|
|
186
|
+
if (raw === void 0) return [];
|
|
187
|
+
if (!Array.isArray(raw)) {
|
|
188
|
+
throw new Error(`Invalid stringset op: ${opName} must be an array.`);
|
|
189
|
+
}
|
|
190
|
+
return raw.map((m) => String(m));
|
|
191
|
+
};
|
|
192
|
+
return {
|
|
193
|
+
add: toMembers(obj.$add, "$add"),
|
|
194
|
+
remove: toMembers(obj.$remove, "$remove"),
|
|
195
|
+
clear: obj.$clear === true
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
function writeField(rm, declaredType, key, value, modelName) {
|
|
199
|
+
const kind = declaredType && isKnownFieldType(declaredType) ? fieldWriteKind(declaredType) : "scalar";
|
|
200
|
+
if (Array.isArray(value)) {
|
|
201
|
+
if (kind !== "stringset") {
|
|
202
|
+
throw new Error(
|
|
203
|
+
`Cannot write array value to field "${key}" on model "${modelName}": its declared type could not be resolved to a collection (stringset). Collection fields require schema metadata in the document (_meta_${modelName}); the model must be saved by a client at least once before a workflow writes one of its collection fields.`
|
|
204
|
+
);
|
|
205
|
+
}
|
|
206
|
+
replaceStringSet(rm, key, value);
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
const op = parseStringSetOp(value);
|
|
210
|
+
if (op) {
|
|
211
|
+
if (kind !== "stringset") {
|
|
212
|
+
throw new Error(
|
|
213
|
+
`Cannot apply a stringset op ({ $add/$remove/$clear }) to field "${key}" on model "${modelName}": its declared type is ${declaredType ? `"${declaredType}"` : "unresolved"}, not a collection (stringset). Op-objects are only valid for stringset / refersToMany fields with schema metadata (_meta_${modelName}).`
|
|
214
|
+
);
|
|
215
|
+
}
|
|
216
|
+
applyStringSetDelta(ensureStringSetYMap(rm, key), op);
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
if (kind === "stringset") {
|
|
220
|
+
throw new Error(
|
|
221
|
+
`Field "${key}" on model "${modelName}" is a stringset and requires an array (replace) or { $add/$remove/$clear } (delta) value; received ${value === null ? "null" : typeof value}.`
|
|
222
|
+
);
|
|
223
|
+
}
|
|
224
|
+
rm.set(key, value);
|
|
225
|
+
}
|
|
226
|
+
function registerFunctionDefaultGenerator(name, fn) {
|
|
227
|
+
FUNCTION_DEFAULT_GENERATORS.set(name, fn);
|
|
228
|
+
}
|
|
229
|
+
function decodeFunctionDefault(name) {
|
|
230
|
+
return FUNCTION_DEFAULT_GENERATORS.get(name);
|
|
231
|
+
}
|
|
232
|
+
function resolveDefaultValue(rawDefault, opts = {}) {
|
|
233
|
+
if (typeof rawDefault === "function") return rawDefault();
|
|
234
|
+
if (typeof rawDefault === "string" && rawDefault.startsWith("$")) {
|
|
235
|
+
if (rawDefault.startsWith("$$")) return rawDefault.slice(1);
|
|
236
|
+
const name = rawDefault.slice(1);
|
|
237
|
+
const gen = opts.decode?.(name) ?? decodeFunctionDefault(name);
|
|
238
|
+
if (!gen) {
|
|
239
|
+
throw new Error(
|
|
240
|
+
`Unknown function default "${rawDefault}" for field "${opts.fieldName ?? "?"}"${opts.modelName ? ` on model "${opts.modelName}"` : ""}: no generator is registered for "${name}". Register it via registerFunctionDefaultGenerator("${name}", fn) so the server can populate the field the same way the client does.`
|
|
241
|
+
);
|
|
242
|
+
}
|
|
243
|
+
return gen();
|
|
244
|
+
}
|
|
245
|
+
return rawDefault;
|
|
246
|
+
}
|
|
247
|
+
function applyDefaultsFromSchema(fields, data, opts = {}) {
|
|
248
|
+
for (const [fieldName, field] of Object.entries(fields)) {
|
|
249
|
+
if (fieldName === "id") continue;
|
|
250
|
+
if (!field || field.default === void 0) continue;
|
|
251
|
+
if (field.default === UNKNOWN_FUNCTION_DEFAULT) {
|
|
252
|
+
continue;
|
|
253
|
+
}
|
|
254
|
+
if (Object.prototype.hasOwnProperty.call(data, fieldName) && data[fieldName] !== void 0) {
|
|
255
|
+
continue;
|
|
256
|
+
}
|
|
257
|
+
data[fieldName] = resolveDefaultValue(field.default, {
|
|
258
|
+
fieldName,
|
|
259
|
+
modelName: opts.modelName,
|
|
260
|
+
decode: opts.decodeFunctionDefault
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
return data;
|
|
264
|
+
}
|
|
265
|
+
function applyAutoStampsFromSchema(fields, data, opts) {
|
|
266
|
+
const { isNew, now } = opts;
|
|
267
|
+
for (const [fieldName, field] of Object.entries(fields)) {
|
|
268
|
+
const stamp = field?.autoStamp;
|
|
269
|
+
if (!stamp) continue;
|
|
270
|
+
const explicit = Object.prototype.hasOwnProperty.call(data, fieldName) && data[fieldName] !== null && data[fieldName] !== void 0;
|
|
271
|
+
if (explicit) continue;
|
|
272
|
+
if (stamp === "create" && !isNew) continue;
|
|
273
|
+
data[fieldName] = now;
|
|
274
|
+
}
|
|
275
|
+
return data;
|
|
276
|
+
}
|
|
277
|
+
var Y2, import_ulid, KNOWN_FIELD_TYPE_MAP, KNOWN_FIELD_TYPES, FUNCTION_DEFAULT_GENERATORS, UNKNOWN_FUNCTION_DEFAULT;
|
|
278
|
+
var init_writeLifecycle = __esm({
|
|
279
|
+
"src/models/writeLifecycle.ts"() {
|
|
280
|
+
"use strict";
|
|
281
|
+
Y2 = __toESM(require("yjs"), 1);
|
|
282
|
+
import_ulid = require("ulid");
|
|
283
|
+
KNOWN_FIELD_TYPE_MAP = {
|
|
284
|
+
string: true,
|
|
285
|
+
number: true,
|
|
286
|
+
boolean: true,
|
|
287
|
+
date: true,
|
|
288
|
+
id: true,
|
|
289
|
+
stringset: true
|
|
290
|
+
};
|
|
291
|
+
KNOWN_FIELD_TYPES = new Set(Object.keys(KNOWN_FIELD_TYPE_MAP));
|
|
292
|
+
FUNCTION_DEFAULT_GENERATORS = /* @__PURE__ */ new Map();
|
|
293
|
+
registerFunctionDefaultGenerator("generate_ulid", () => (0, import_ulid.ulid)());
|
|
294
|
+
UNKNOWN_FUNCTION_DEFAULT = "$unknown_function";
|
|
295
|
+
}
|
|
296
|
+
});
|
|
297
|
+
|
|
103
298
|
// src/models/metaSync.ts
|
|
104
299
|
function inferFieldType(value) {
|
|
105
300
|
if (isStringSetYMap(value)) return "stringset";
|
|
@@ -121,7 +316,10 @@ function encodeDefault(value) {
|
|
|
121
316
|
if (value === void 0 || value === null) return void 0;
|
|
122
317
|
if (typeof value === "function") {
|
|
123
318
|
const name = KNOWN_FUNCTION_DEFAULTS.get(value);
|
|
124
|
-
return name ? `$${name}` :
|
|
319
|
+
return name ? `$${name}` : UNKNOWN_FUNCTION_DEFAULT;
|
|
320
|
+
}
|
|
321
|
+
if (typeof value === "string" && value.startsWith("$")) {
|
|
322
|
+
return `$${value}`;
|
|
125
323
|
}
|
|
126
324
|
return value;
|
|
127
325
|
}
|
|
@@ -147,7 +345,7 @@ function syncModelMeta(yDoc, modelName, schema) {
|
|
|
147
345
|
if (compoundConstraints.length > 0) {
|
|
148
346
|
let constraints = meta.get("_constraints");
|
|
149
347
|
if (!constraints) {
|
|
150
|
-
constraints = new
|
|
348
|
+
constraints = new Y3.Map();
|
|
151
349
|
meta.set("_constraints", constraints);
|
|
152
350
|
}
|
|
153
351
|
for (const constraint of compoundConstraints) {
|
|
@@ -158,7 +356,7 @@ function syncModelMeta(yDoc, modelName, schema) {
|
|
|
158
356
|
if (relationships && Object.keys(relationships).length > 0) {
|
|
159
357
|
let rels = meta.get("_relationships");
|
|
160
358
|
if (!rels) {
|
|
161
|
-
rels = new
|
|
359
|
+
rels = new Y3.Map();
|
|
162
360
|
meta.set("_relationships", rels);
|
|
163
361
|
}
|
|
164
362
|
for (const [relName, relConfig] of Object.entries(relationships)) {
|
|
@@ -170,7 +368,7 @@ function syncModelMeta(yDoc, modelName, schema) {
|
|
|
170
368
|
function syncFieldMeta(metaMap, fieldName, fieldOpts) {
|
|
171
369
|
let fieldMeta = metaMap.get(fieldName);
|
|
172
370
|
if (!fieldMeta) {
|
|
173
|
-
fieldMeta = new
|
|
371
|
+
fieldMeta = new Y3.Map();
|
|
174
372
|
metaMap.set(fieldName, fieldMeta);
|
|
175
373
|
}
|
|
176
374
|
setIfChanged(fieldMeta, "type", fieldOpts.type);
|
|
@@ -187,7 +385,7 @@ function syncFieldMeta(metaMap, fieldName, fieldOpts) {
|
|
|
187
385
|
function syncConstraintMeta(constraintsMap, constraint) {
|
|
188
386
|
let cMeta = constraintsMap.get(constraint.name);
|
|
189
387
|
if (!cMeta) {
|
|
190
|
-
cMeta = new
|
|
388
|
+
cMeta = new Y3.Map();
|
|
191
389
|
constraintsMap.set(constraint.name, cMeta);
|
|
192
390
|
}
|
|
193
391
|
setIfChanged(cMeta, "type", "unique");
|
|
@@ -197,7 +395,7 @@ function syncConstraintMeta(constraintsMap, constraint) {
|
|
|
197
395
|
function syncRelationshipMeta(relsMap, relName, relConfig) {
|
|
198
396
|
let relMeta = relsMap.get(relName);
|
|
199
397
|
if (!relMeta) {
|
|
200
|
-
relMeta = new
|
|
398
|
+
relMeta = new Y3.Map();
|
|
201
399
|
relsMap.set(relName, relMeta);
|
|
202
400
|
}
|
|
203
401
|
for (const [key, value] of Object.entries(relConfig)) {
|
|
@@ -212,7 +410,7 @@ function syncInferredMeta(yDoc, modelName, recordData) {
|
|
|
212
410
|
if (fieldName.startsWith("_")) continue;
|
|
213
411
|
let fieldMeta = meta.get(fieldName);
|
|
214
412
|
if (!fieldMeta) {
|
|
215
|
-
fieldMeta = new
|
|
413
|
+
fieldMeta = new Y3.Map();
|
|
216
414
|
meta.set(fieldName, fieldMeta);
|
|
217
415
|
}
|
|
218
416
|
if (!fieldMeta.has("type")) {
|
|
@@ -228,34 +426,378 @@ function setIfChanged(map, key, value) {
|
|
|
228
426
|
map.set(key, value);
|
|
229
427
|
}
|
|
230
428
|
}
|
|
231
|
-
var
|
|
429
|
+
var Y3, KNOWN_FUNCTION_DEFAULTS, _syncedCache;
|
|
232
430
|
var init_metaSync = __esm({
|
|
233
431
|
"src/models/metaSync.ts"() {
|
|
234
432
|
"use strict";
|
|
235
|
-
|
|
433
|
+
Y3 = __toESM(require("yjs"), 1);
|
|
236
434
|
init_yjsValues();
|
|
435
|
+
init_writeLifecycle();
|
|
237
436
|
KNOWN_FUNCTION_DEFAULTS = /* @__PURE__ */ new WeakMap();
|
|
238
437
|
_syncedCache = /* @__PURE__ */ new WeakMap();
|
|
239
438
|
}
|
|
240
439
|
});
|
|
241
440
|
|
|
441
|
+
// src/utils/uniqueIndex.ts
|
|
442
|
+
function buildUniqueKey(recordData, fields) {
|
|
443
|
+
const keyParts = [];
|
|
444
|
+
for (const field of fields) {
|
|
445
|
+
const value = recordData instanceof Y4.Map ? recordData.get(field) : recordData[field];
|
|
446
|
+
if (value === null || value === void 0) {
|
|
447
|
+
return null;
|
|
448
|
+
}
|
|
449
|
+
keyParts.push(String(value));
|
|
450
|
+
}
|
|
451
|
+
return keyParts.join("|");
|
|
452
|
+
}
|
|
453
|
+
function uniqueIndexMapName(modelName, constraintName) {
|
|
454
|
+
return `_uniqueIdx_${modelName}_${constraintName}`;
|
|
455
|
+
}
|
|
456
|
+
function fieldUniqueConstraintName(modelName, fieldName) {
|
|
457
|
+
return `${modelName}_${fieldName}_unique`;
|
|
458
|
+
}
|
|
459
|
+
var Y4;
|
|
460
|
+
var init_uniqueIndex = __esm({
|
|
461
|
+
"src/utils/uniqueIndex.ts"() {
|
|
462
|
+
"use strict";
|
|
463
|
+
Y4 = __toESM(require("yjs"), 1);
|
|
464
|
+
}
|
|
465
|
+
});
|
|
466
|
+
|
|
467
|
+
// src/utils/largeDocuments.ts
|
|
468
|
+
var Y5;
|
|
469
|
+
var init_largeDocuments = __esm({
|
|
470
|
+
"src/utils/largeDocuments.ts"() {
|
|
471
|
+
"use strict";
|
|
472
|
+
Y5 = __toESM(require("yjs"), 1);
|
|
473
|
+
init_yjsValues();
|
|
474
|
+
}
|
|
475
|
+
});
|
|
476
|
+
|
|
477
|
+
// src/models/OrmContext.ts
|
|
478
|
+
var OrmContext, defaultOrmContext, liveOrmContexts;
|
|
479
|
+
var init_OrmContext = __esm({
|
|
480
|
+
"src/models/OrmContext.ts"() {
|
|
481
|
+
"use strict";
|
|
482
|
+
OrmContext = class _OrmContext {
|
|
483
|
+
/** Declared before the field that reads it: static initialization is ordered. */
|
|
484
|
+
static instanceCounter = 0;
|
|
485
|
+
/**
|
|
486
|
+
* Which instance this is, for diagnostics. A process holding several clients
|
|
487
|
+
* needs a way to say WHICH one a warning is about, so every context takes the
|
|
488
|
+
* next number as it is created and keeps it for its lifetime.
|
|
489
|
+
*/
|
|
490
|
+
instanceId = ++_OrmContext.instanceCounter;
|
|
491
|
+
/** The engine this instance's models read and write through. */
|
|
492
|
+
dbEngine = null;
|
|
493
|
+
connectedDocuments = /* @__PURE__ */ new Map();
|
|
494
|
+
/** `docId_modelName` → the Y.Map that document holds for that model. */
|
|
495
|
+
documentYMaps = /* @__PURE__ */ new Map();
|
|
496
|
+
/** `subscribe()` callbacks, by model name. */
|
|
497
|
+
listenersMap = /* @__PURE__ */ new Map();
|
|
498
|
+
// Default-document resolution
|
|
499
|
+
modelNameToDefaultDocId = /* @__PURE__ */ new Map();
|
|
500
|
+
globalDefaultDocId = void 0;
|
|
501
|
+
defaultDocChangedListeners = /* @__PURE__ */ new Set();
|
|
502
|
+
modelDocMappingChangedListeners = /* @__PURE__ */ new Set();
|
|
503
|
+
/** Format-2 ("large document", #2816) record stores by document id. */
|
|
504
|
+
format2Documents = /* @__PURE__ */ new Map();
|
|
505
|
+
/** Format-2 epoch moves in flight (#2816). */
|
|
506
|
+
format2Transitions = /* @__PURE__ */ new Map();
|
|
507
|
+
/**
|
|
508
|
+
* Nested-Y.Map stringset fields this context has already observed. Per
|
|
509
|
+
* context, not global: a Y.Doc reconnected to a fresh instance has to be
|
|
510
|
+
* observed again by that instance, and a global guard would silently
|
|
511
|
+
* suppress it.
|
|
512
|
+
*/
|
|
513
|
+
observedStringSetMaps = /* @__PURE__ */ new WeakSet();
|
|
514
|
+
/**
|
|
515
|
+
* The registry this instance's schema lookups use. `null` on the standing
|
|
516
|
+
* default context, where callers fall back to the global singleton.
|
|
517
|
+
*/
|
|
518
|
+
modelRegistry = null;
|
|
519
|
+
/** Model classes routed to this context. */
|
|
520
|
+
boundModels = /* @__PURE__ */ new Set();
|
|
521
|
+
/** True once {@link destroy} has run; bound classes keep pointing here. */
|
|
522
|
+
destroyed = false;
|
|
523
|
+
/** Yjs `unobserve` thunks by owning document id. */
|
|
524
|
+
observerDisposers = /* @__PURE__ */ new Map();
|
|
525
|
+
/** Teardown the owner (the document manager) registers for `destroy()`. */
|
|
526
|
+
teardownHooks = /* @__PURE__ */ new Set();
|
|
527
|
+
static NO_DOCUMENT_KEY = "__no_document__";
|
|
528
|
+
/**
|
|
529
|
+
* Record how to remove an observer this context installed. Every `observe()`
|
|
530
|
+
* in the ORM pairs with one of these: without it a torn-down instance's
|
|
531
|
+
* callbacks keep firing on a Y.Doc that outlives it.
|
|
532
|
+
*/
|
|
533
|
+
registerObserverDisposer(docId, dispose) {
|
|
534
|
+
const key = docId ?? _OrmContext.NO_DOCUMENT_KEY;
|
|
535
|
+
const list = this.observerDisposers.get(key);
|
|
536
|
+
if (list) list.push(dispose);
|
|
537
|
+
else this.observerDisposers.set(key, [dispose]);
|
|
538
|
+
}
|
|
539
|
+
/** Remove every observer this context installed for `docId`. */
|
|
540
|
+
disposeObserversForDocument(docId) {
|
|
541
|
+
const list = this.observerDisposers.get(docId);
|
|
542
|
+
if (!list) return;
|
|
543
|
+
this.observerDisposers.delete(docId);
|
|
544
|
+
for (const dispose of list) {
|
|
545
|
+
try {
|
|
546
|
+
dispose();
|
|
547
|
+
} catch {
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
disposeAllObservers() {
|
|
552
|
+
const buckets = Array.from(this.observerDisposers.values());
|
|
553
|
+
this.observerDisposers.clear();
|
|
554
|
+
for (const list of buckets) {
|
|
555
|
+
for (const dispose of list) {
|
|
556
|
+
try {
|
|
557
|
+
dispose();
|
|
558
|
+
} catch {
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
/** Run `hook` as part of `destroy()` (the format-2 binding registers here). */
|
|
564
|
+
onDestroy(hook) {
|
|
565
|
+
this.teardownHooks.add(hook);
|
|
566
|
+
}
|
|
567
|
+
/** The record store for `docId`, or `null` when the document is format 1. */
|
|
568
|
+
getFormat2Store(docId) {
|
|
569
|
+
if (!docId) return null;
|
|
570
|
+
return this.format2Documents.get(docId) ?? null;
|
|
571
|
+
}
|
|
572
|
+
/**
|
|
573
|
+
* The epoch move a write to `docId` has to wait out (#2816, behavior 10), or
|
|
574
|
+
* `null` when none is in flight.
|
|
575
|
+
*/
|
|
576
|
+
format2WritesHeld(docId) {
|
|
577
|
+
if (!docId) return null;
|
|
578
|
+
return this.format2Transitions.get(docId) ?? null;
|
|
579
|
+
}
|
|
580
|
+
/** Run an epoch move with `docId`'s local writes held back (#2816). */
|
|
581
|
+
async holdFormat2Writes(docId, run) {
|
|
582
|
+
const inFlight = this.format2Transitions.get(docId);
|
|
583
|
+
if (inFlight) await inFlight.catch(() => {
|
|
584
|
+
});
|
|
585
|
+
let release;
|
|
586
|
+
const held = new Promise((resolve) => {
|
|
587
|
+
release = resolve;
|
|
588
|
+
});
|
|
589
|
+
this.format2Transitions.set(docId, held);
|
|
590
|
+
try {
|
|
591
|
+
return await run();
|
|
592
|
+
} finally {
|
|
593
|
+
if (this.format2Transitions.get(docId) === held) {
|
|
594
|
+
this.format2Transitions.delete(docId);
|
|
595
|
+
}
|
|
596
|
+
release();
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
/** Notify `subscribe()` callbacks registered on this context for `modelName`. */
|
|
600
|
+
notifyListeners(modelName, log, onError) {
|
|
601
|
+
const listeners = this.listenersMap.get(modelName);
|
|
602
|
+
if (!listeners) return;
|
|
603
|
+
log?.(`Notifying ${listeners.size} listeners for ${modelName}`);
|
|
604
|
+
listeners.forEach((callback) => {
|
|
605
|
+
try {
|
|
606
|
+
callback();
|
|
607
|
+
} catch (e) {
|
|
608
|
+
onError?.(e);
|
|
609
|
+
}
|
|
610
|
+
});
|
|
611
|
+
}
|
|
612
|
+
// ---- Default-document resolution (the `BaseModel` statics delegate here) ----
|
|
613
|
+
setModelDefaultDocumentId(modelName, docId) {
|
|
614
|
+
const previous = this.modelNameToDefaultDocId.get(modelName);
|
|
615
|
+
this.modelNameToDefaultDocId.set(modelName, docId);
|
|
616
|
+
this.announceModelDocMapping(modelName, previous, docId);
|
|
617
|
+
}
|
|
618
|
+
removeModelDefaultDocumentId(modelName) {
|
|
619
|
+
const previous = this.modelNameToDefaultDocId.get(modelName);
|
|
620
|
+
this.modelNameToDefaultDocId.delete(modelName);
|
|
621
|
+
this.announceModelDocMapping(modelName, previous, void 0);
|
|
622
|
+
}
|
|
623
|
+
clearModelDefaultDocumentIds() {
|
|
624
|
+
const entries = Array.from(this.modelNameToDefaultDocId.entries());
|
|
625
|
+
this.modelNameToDefaultDocId.clear();
|
|
626
|
+
for (const [modelName, previous] of entries) {
|
|
627
|
+
this.announceModelDocMapping(modelName, previous, void 0);
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
setGlobalDefaultDocumentId(docId) {
|
|
631
|
+
const previous = this.globalDefaultDocId;
|
|
632
|
+
this.globalDefaultDocId = docId;
|
|
633
|
+
this.announceDefaultDoc(previous, docId);
|
|
634
|
+
}
|
|
635
|
+
clearGlobalDefaultDocumentId() {
|
|
636
|
+
const previous = this.globalDefaultDocId;
|
|
637
|
+
this.globalDefaultDocId = void 0;
|
|
638
|
+
this.announceDefaultDoc(previous, void 0);
|
|
639
|
+
}
|
|
640
|
+
getModelDefaultDocumentMapping() {
|
|
641
|
+
return Object.fromEntries(this.modelNameToDefaultDocId.entries());
|
|
642
|
+
}
|
|
643
|
+
getDocumentIdForModel(modelName) {
|
|
644
|
+
return this.modelNameToDefaultDocId.get(modelName);
|
|
645
|
+
}
|
|
646
|
+
getGlobalDefaultDocumentId() {
|
|
647
|
+
return this.globalDefaultDocId;
|
|
648
|
+
}
|
|
649
|
+
onDefaultDocChanged(listener) {
|
|
650
|
+
this.defaultDocChangedListeners.add(listener);
|
|
651
|
+
return () => this.defaultDocChangedListeners.delete(listener);
|
|
652
|
+
}
|
|
653
|
+
onModelDocMappingChanged(listener) {
|
|
654
|
+
this.modelDocMappingChangedListeners.add(listener);
|
|
655
|
+
return () => this.modelDocMappingChangedListeners.delete(listener);
|
|
656
|
+
}
|
|
657
|
+
/** Drop the model→document defaults that point at a disconnected document. */
|
|
658
|
+
clearMappingsForDocId(docId) {
|
|
659
|
+
const toRemove = [];
|
|
660
|
+
for (const [modelName, mappedDocId] of this.modelNameToDefaultDocId) {
|
|
661
|
+
if (mappedDocId === docId) toRemove.push(modelName);
|
|
662
|
+
}
|
|
663
|
+
for (const modelName of toRemove) {
|
|
664
|
+
this.removeModelDefaultDocumentId(modelName);
|
|
665
|
+
}
|
|
666
|
+
if (this.globalDefaultDocId === docId) {
|
|
667
|
+
this.clearGlobalDefaultDocumentId();
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
announceDefaultDoc(previous, current) {
|
|
671
|
+
for (const listener of this.defaultDocChangedListeners) {
|
|
672
|
+
try {
|
|
673
|
+
listener({ previous, current });
|
|
674
|
+
} catch {
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
announceModelDocMapping(modelName, previous, current) {
|
|
679
|
+
for (const listener of this.modelDocMappingChangedListeners) {
|
|
680
|
+
try {
|
|
681
|
+
listener({ modelName, previous, current });
|
|
682
|
+
} catch {
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
/**
|
|
687
|
+
* Tear this instance down: observers off, engine destroyed, state cleared.
|
|
688
|
+
*
|
|
689
|
+
* Deliberately does NOT unbind its model classes. They keep resolving this
|
|
690
|
+
* context, whose engine is now null, so an operation through them throws the
|
|
691
|
+
* ordinary not-initialized error instead of silently landing on whatever
|
|
692
|
+
* other instance happens to be live (#3039, behavior 7). Only a later
|
|
693
|
+
* `initJsBao` may rebind a class whose context is destroyed.
|
|
694
|
+
*/
|
|
695
|
+
async destroy() {
|
|
696
|
+
if (this.destroyed) return;
|
|
697
|
+
this.destroyed = true;
|
|
698
|
+
this.disposeAllObservers();
|
|
699
|
+
const hooks = Array.from(this.teardownHooks);
|
|
700
|
+
this.teardownHooks.clear();
|
|
701
|
+
for (const hook of hooks) {
|
|
702
|
+
try {
|
|
703
|
+
await hook();
|
|
704
|
+
} catch {
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
const engine = this.dbEngine;
|
|
708
|
+
this.dbEngine = null;
|
|
709
|
+
if (engine) {
|
|
710
|
+
try {
|
|
711
|
+
await engine.destroy();
|
|
712
|
+
} catch {
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
this.connectedDocuments.clear();
|
|
716
|
+
this.documentYMaps.clear();
|
|
717
|
+
this.listenersMap.clear();
|
|
718
|
+
this.modelNameToDefaultDocId.clear();
|
|
719
|
+
this.globalDefaultDocId = void 0;
|
|
720
|
+
this.defaultDocChangedListeners.clear();
|
|
721
|
+
this.modelDocMappingChangedListeners.clear();
|
|
722
|
+
this.format2Documents.clear();
|
|
723
|
+
this.format2Transitions.clear();
|
|
724
|
+
this.observedStringSetMaps = /* @__PURE__ */ new WeakSet();
|
|
725
|
+
liveOrmContexts.delete(this);
|
|
726
|
+
if (defaultOrmContext === this) {
|
|
727
|
+
defaultOrmContext = new _OrmContext();
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
};
|
|
731
|
+
defaultOrmContext = new OrmContext();
|
|
732
|
+
liveOrmContexts = /* @__PURE__ */ new Set();
|
|
733
|
+
}
|
|
734
|
+
});
|
|
735
|
+
|
|
736
|
+
// src/models/format2QueryProjection.ts
|
|
737
|
+
var FORMAT2_QUERY_PROJECTION_DDL;
|
|
738
|
+
var init_format2QueryProjection = __esm({
|
|
739
|
+
"src/models/format2QueryProjection.ts"() {
|
|
740
|
+
"use strict";
|
|
741
|
+
FORMAT2_QUERY_PROJECTION_DDL = `
|
|
742
|
+
CREATE TABLE IF NOT EXISTS _query_projection (
|
|
743
|
+
doc_id TEXT NOT NULL,
|
|
744
|
+
model TEXT NOT NULL,
|
|
745
|
+
PRIMARY KEY (doc_id, model)
|
|
746
|
+
)`.trim();
|
|
747
|
+
}
|
|
748
|
+
});
|
|
749
|
+
|
|
750
|
+
// src/models/format2Observer.ts
|
|
751
|
+
var Y6;
|
|
752
|
+
var init_format2Observer = __esm({
|
|
753
|
+
"src/models/format2Observer.ts"() {
|
|
754
|
+
"use strict";
|
|
755
|
+
Y6 = __toESM(require("yjs"), 1);
|
|
756
|
+
init_largeDocuments();
|
|
757
|
+
}
|
|
758
|
+
});
|
|
759
|
+
|
|
760
|
+
// src/models/format2ClientWrite.ts
|
|
761
|
+
var init_format2ClientWrite = __esm({
|
|
762
|
+
"src/models/format2ClientWrite.ts"() {
|
|
763
|
+
"use strict";
|
|
764
|
+
}
|
|
765
|
+
});
|
|
766
|
+
|
|
767
|
+
// src/models/format2OfflineWindow.ts
|
|
768
|
+
var DAY_MS;
|
|
769
|
+
var init_format2OfflineWindow = __esm({
|
|
770
|
+
"src/models/format2OfflineWindow.ts"() {
|
|
771
|
+
"use strict";
|
|
772
|
+
DAY_MS = 24 * 60 * 60 * 1e3;
|
|
773
|
+
}
|
|
774
|
+
});
|
|
775
|
+
|
|
242
776
|
// src/models/BaseModel.ts
|
|
243
777
|
function generateULID() {
|
|
244
|
-
return (0,
|
|
778
|
+
return (0, import_ulid2.ulid)();
|
|
245
779
|
}
|
|
246
|
-
var
|
|
780
|
+
var Y7, import_ulid2, Logger;
|
|
247
781
|
var init_BaseModel = __esm({
|
|
248
782
|
"src/models/BaseModel.ts"() {
|
|
249
783
|
"use strict";
|
|
250
|
-
|
|
251
|
-
|
|
784
|
+
Y7 = __toESM(require("yjs"), 1);
|
|
785
|
+
import_ulid2 = require("ulid");
|
|
252
786
|
init_StringSet();
|
|
253
787
|
init_documentTypes();
|
|
254
788
|
init_DocumentQueryTranslator();
|
|
255
789
|
init_CursorManager();
|
|
256
790
|
init_sql();
|
|
257
791
|
init_metaSync();
|
|
792
|
+
init_writeLifecycle();
|
|
258
793
|
init_yjsValues();
|
|
794
|
+
init_uniqueIndex();
|
|
795
|
+
init_largeDocuments();
|
|
796
|
+
init_OrmContext();
|
|
797
|
+
init_format2QueryProjection();
|
|
798
|
+
init_format2Observer();
|
|
799
|
+
init_format2ClientWrite();
|
|
800
|
+
init_format2OfflineWindow();
|
|
259
801
|
Logger = class {
|
|
260
802
|
static _logLevel = 1 /* ERROR */;
|
|
261
803
|
static _logCallback = null;
|
|
@@ -342,6 +884,7 @@ var init_ModelRegistry = __esm({
|
|
|
342
884
|
"use strict";
|
|
343
885
|
init_BaseModel();
|
|
344
886
|
init_relationshipManager();
|
|
887
|
+
init_format2QueryProjection();
|
|
345
888
|
}
|
|
346
889
|
});
|
|
347
890
|
|
|
@@ -349,19 +892,37 @@ var init_ModelRegistry = __esm({
|
|
|
349
892
|
var cloudflare_exports = {};
|
|
350
893
|
__export(cloudflare_exports, {
|
|
351
894
|
DOClientEngine: () => DOClientEngine,
|
|
895
|
+
applyAutoStampsFromSchema: () => applyAutoStampsFromSchema,
|
|
896
|
+
applyDefaultsFromSchema: () => applyDefaultsFromSchema,
|
|
897
|
+
applyStringSetChange: () => applyStringSetChange,
|
|
898
|
+
applyStringSetDelta: () => applyStringSetDelta,
|
|
899
|
+
assertNever: () => assertNever,
|
|
900
|
+
buildUniqueKey: () => buildUniqueKey,
|
|
352
901
|
clearMetaSyncCache: () => clearMetaSyncCache,
|
|
353
902
|
connectDoDb: () => connectDoDb,
|
|
903
|
+
decodeFunctionDefault: () => decodeFunctionDefault,
|
|
904
|
+
discoverDeclaredModel: () => discoverDeclaredModel,
|
|
354
905
|
discoverModelNames: () => discoverModelNames,
|
|
355
906
|
discoverSchema: () => discoverSchema,
|
|
907
|
+
ensureStringSetYMap: () => ensureStringSetYMap,
|
|
908
|
+
fieldUniqueConstraintName: () => fieldUniqueConstraintName,
|
|
909
|
+
fieldWriteKind: () => fieldWriteKind,
|
|
356
910
|
getActiveDOEngine: () => getActiveDOEngine,
|
|
357
911
|
inferFieldType: () => inferFieldType,
|
|
358
912
|
initJsBaoDO: () => initJsBaoDO,
|
|
913
|
+
isKnownFieldType: () => isKnownFieldType,
|
|
359
914
|
loadSchemaFromTomlString: () => loadSchemaFromTomlString,
|
|
915
|
+
parseStringSetOp: () => parseStringSetOp,
|
|
360
916
|
registerFunctionDefault: () => registerFunctionDefault,
|
|
917
|
+
registerFunctionDefaultGenerator: () => registerFunctionDefaultGenerator,
|
|
918
|
+
replaceStringSet: () => replaceStringSet,
|
|
361
919
|
resetJsBaoDO: () => resetJsBaoDO,
|
|
920
|
+
resolveDefaultValue: () => resolveDefaultValue,
|
|
362
921
|
schemaToToml: () => schemaToToml,
|
|
363
922
|
syncInferredMeta: () => syncInferredMeta,
|
|
364
|
-
syncModelMeta: () => syncModelMeta
|
|
923
|
+
syncModelMeta: () => syncModelMeta,
|
|
924
|
+
uniqueIndexMapName: () => uniqueIndexMapName,
|
|
925
|
+
writeField: () => writeField
|
|
365
926
|
});
|
|
366
927
|
module.exports = __toCommonJS(cloudflare_exports);
|
|
367
928
|
|
|
@@ -400,6 +961,32 @@ var DatabaseEngine = class {
|
|
|
400
961
|
getTableName(_modelName) {
|
|
401
962
|
throw new Error("Method not implemented.");
|
|
402
963
|
}
|
|
964
|
+
/**
|
|
965
|
+
* A SYNCHRONOUS SQL executor over this engine's database, used by the
|
|
966
|
+
* large-document (format 2) record store. That store commits a merged
|
|
967
|
+
* record row and its pending-operation entry as one transaction — the
|
|
968
|
+
* barrier a `save()` resolves behind — which the async `query()` API cannot
|
|
969
|
+
* express. Engines whose underlying SQLite is synchronous (better-sqlite3,
|
|
970
|
+
* SQL.js) provide it; anything else leaves it undefined and cannot host a
|
|
971
|
+
* large document.
|
|
972
|
+
*/
|
|
973
|
+
createFormat2Sql;
|
|
974
|
+
/**
|
|
975
|
+
* Whether what {@link createFormat2Sql} writes survives this process.
|
|
976
|
+
*
|
|
977
|
+
* On a large document the merged record view IS the document: the Y.Doc
|
|
978
|
+
* holds one epoch's overlay, and everything else — including a record a
|
|
979
|
+
* `save()` has already resolved, and the pending write that still owes it to
|
|
980
|
+
* the server — lives only in this store. An engine whose database is in
|
|
981
|
+
* memory therefore cannot host one: a reload does not cost a cache, it costs
|
|
982
|
+
* the document and the writes nobody has acknowledged yet.
|
|
983
|
+
*
|
|
984
|
+
* The platform is asked separately about its storage quota; this answers the
|
|
985
|
+
* half only the engine knows. An engine that does not implement it is taken
|
|
986
|
+
* at the platform's word, which is what keeps hosts with storage of their
|
|
987
|
+
* own — a worker handed a file store, a test — working unchanged.
|
|
988
|
+
*/
|
|
989
|
+
format2StorageIsDurable;
|
|
403
990
|
// Transaction support
|
|
404
991
|
async withTransaction(_callback) {
|
|
405
992
|
throw new Error("Method not implemented.");
|
|
@@ -1242,7 +1829,7 @@ function connectDoDb(options) {
|
|
|
1242
1829
|
}
|
|
1243
1830
|
|
|
1244
1831
|
// src/utils/yDocSchema.ts
|
|
1245
|
-
var
|
|
1832
|
+
var Y8 = __toESM(require("yjs"), 1);
|
|
1246
1833
|
init_yjsValues();
|
|
1247
1834
|
function discoverSchema(yDoc) {
|
|
1248
1835
|
const models = {};
|
|
@@ -1265,6 +1852,12 @@ function discoverSchema(yDoc) {
|
|
|
1265
1852
|
}
|
|
1266
1853
|
return { models };
|
|
1267
1854
|
}
|
|
1855
|
+
function discoverDeclaredModel(yDoc, modelName) {
|
|
1856
|
+
const key = `_meta_${modelName}`;
|
|
1857
|
+
if (!yDoc.share.has(key)) return void 0;
|
|
1858
|
+
const map = materializeMap(yDoc, key);
|
|
1859
|
+
return map ? readModelMeta(map) : void 0;
|
|
1860
|
+
}
|
|
1268
1861
|
function discoverModelNames(yDoc) {
|
|
1269
1862
|
const names = [];
|
|
1270
1863
|
for (const key of yDoc.share.keys()) {
|
|
@@ -1277,7 +1870,7 @@ function discoverModelNames(yDoc) {
|
|
|
1277
1870
|
function materializeMap(yDoc, key) {
|
|
1278
1871
|
try {
|
|
1279
1872
|
const map = yDoc.getMap(key);
|
|
1280
|
-
return map instanceof
|
|
1873
|
+
return map instanceof Y8.Map ? map : null;
|
|
1281
1874
|
} catch {
|
|
1282
1875
|
return null;
|
|
1283
1876
|
}
|
|
@@ -1287,11 +1880,11 @@ function readModelMeta(metaMap) {
|
|
|
1287
1880
|
let constraints;
|
|
1288
1881
|
let relationships;
|
|
1289
1882
|
for (const [key, value] of metaMap.entries()) {
|
|
1290
|
-
if (key === "_constraints" && value instanceof
|
|
1883
|
+
if (key === "_constraints" && value instanceof Y8.Map) {
|
|
1291
1884
|
constraints = readConstraints(value);
|
|
1292
|
-
} else if (key === "_relationships" && value instanceof
|
|
1885
|
+
} else if (key === "_relationships" && value instanceof Y8.Map) {
|
|
1293
1886
|
relationships = readRelationships(value);
|
|
1294
|
-
} else if (value instanceof
|
|
1887
|
+
} else if (value instanceof Y8.Map) {
|
|
1295
1888
|
fields[key] = readFieldMeta(value);
|
|
1296
1889
|
}
|
|
1297
1890
|
}
|
|
@@ -1326,7 +1919,7 @@ function inferModelFromData(dataMap) {
|
|
|
1326
1919
|
const fields = {};
|
|
1327
1920
|
let sampled = 0;
|
|
1328
1921
|
for (const [_recordId, recordValue] of dataMap.entries()) {
|
|
1329
|
-
if (!(recordValue instanceof
|
|
1922
|
+
if (!(recordValue instanceof Y8.Map)) continue;
|
|
1330
1923
|
if (++sampled > 5) break;
|
|
1331
1924
|
for (const [fieldName, value] of recordValue.entries()) {
|
|
1332
1925
|
if (fieldName.startsWith("_")) continue;
|
|
@@ -1354,7 +1947,7 @@ function inferTypeFromValue(value) {
|
|
|
1354
1947
|
function readConstraints(constraintsMap) {
|
|
1355
1948
|
const out = {};
|
|
1356
1949
|
for (const [name, value] of constraintsMap.entries()) {
|
|
1357
|
-
if (!(value instanceof
|
|
1950
|
+
if (!(value instanceof Y8.Map)) continue;
|
|
1358
1951
|
let fields = [];
|
|
1359
1952
|
const rawFields = value.get("fields");
|
|
1360
1953
|
if (typeof rawFields === "string") {
|
|
@@ -1373,7 +1966,7 @@ function readConstraints(constraintsMap) {
|
|
|
1373
1966
|
function readRelationships(relsMap) {
|
|
1374
1967
|
const out = {};
|
|
1375
1968
|
for (const [name, value] of relsMap.entries()) {
|
|
1376
|
-
if (!(value instanceof
|
|
1969
|
+
if (!(value instanceof Y8.Map)) continue;
|
|
1377
1970
|
const rel = {};
|
|
1378
1971
|
for (const [k, v] of value.entries()) {
|
|
1379
1972
|
rel[k] = v;
|
|
@@ -1452,6 +2045,7 @@ var import_smol_toml = require("smol-toml");
|
|
|
1452
2045
|
// src/models/schema.ts
|
|
1453
2046
|
init_BaseModel();
|
|
1454
2047
|
init_ModelRegistry();
|
|
2048
|
+
init_uniqueIndex();
|
|
1455
2049
|
function defineModelSchema(input) {
|
|
1456
2050
|
const { name, fields } = input;
|
|
1457
2051
|
const options = {
|
|
@@ -1494,7 +2088,7 @@ function resolveUniqueConstraints(modelName, fields, customConstraints) {
|
|
|
1494
2088
|
for (const [fieldName, options] of fields.entries()) {
|
|
1495
2089
|
if (options.unique) {
|
|
1496
2090
|
resolved.push({
|
|
1497
|
-
name:
|
|
2091
|
+
name: fieldUniqueConstraintName(modelName, fieldName),
|
|
1498
2092
|
fields: [fieldName]
|
|
1499
2093
|
});
|
|
1500
2094
|
}
|
|
@@ -1740,4 +2334,6 @@ function loadSchemaFromTomlString(tomlString, options = {}) {
|
|
|
1740
2334
|
}
|
|
1741
2335
|
|
|
1742
2336
|
// src/cloudflare.ts
|
|
2337
|
+
init_uniqueIndex();
|
|
1743
2338
|
init_metaSync();
|
|
2339
|
+
init_writeLifecycle();
|