js-bao 0.5.0 → 0.5.2
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 +124 -30
- package/dist/browser.cjs +759 -273
- package/dist/browser.d.cts +62 -0
- package/dist/browser.d.ts +62 -0
- package/dist/browser.js +760 -271
- package/dist/client.cjs +53 -6
- package/dist/client.d.cts +149 -0
- package/dist/client.d.ts +149 -0
- package/dist/client.js +49 -4
- package/dist/cloudflare-do.cjs +643 -231
- package/dist/cloudflare-do.d.cts +237 -1
- package/dist/cloudflare-do.d.ts +237 -1
- package/dist/cloudflare-do.js +639 -229
- package/dist/cloudflare.cjs +330 -26
- package/dist/cloudflare.d.cts +360 -1
- package/dist/cloudflare.d.ts +360 -1
- package/dist/cloudflare.js +326 -24
- package/dist/codegen-v2.cjs +139 -21
- package/dist/codegen.cjs +7 -1
- package/dist/index.cjs +724 -232
- package/dist/index.d.cts +98 -1
- package/dist/index.d.ts +98 -1
- package/dist/index.js +721 -229
- package/dist/node.cjs +948 -299
- package/dist/node.d.cts +220 -1
- package/dist/node.d.ts +220 -1
- package/dist/node.js +934 -296
- package/package.json +2 -1
package/dist/cloudflare.cjs
CHANGED
|
@@ -84,9 +84,220 @@ var init_DocumentQueryTranslator = __esm({
|
|
|
84
84
|
}
|
|
85
85
|
});
|
|
86
86
|
|
|
87
|
+
// src/utils/yjsValues.ts
|
|
88
|
+
function isStringSetYMap(value) {
|
|
89
|
+
if (!(value instanceof Y.Map)) return false;
|
|
90
|
+
for (const v of value.values()) {
|
|
91
|
+
if (v !== true) return false;
|
|
92
|
+
}
|
|
93
|
+
return true;
|
|
94
|
+
}
|
|
95
|
+
var Y;
|
|
96
|
+
var init_yjsValues = __esm({
|
|
97
|
+
"src/utils/yjsValues.ts"() {
|
|
98
|
+
"use strict";
|
|
99
|
+
Y = __toESM(require("yjs"), 1);
|
|
100
|
+
}
|
|
101
|
+
});
|
|
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
|
+
|
|
87
298
|
// src/models/metaSync.ts
|
|
88
299
|
function inferFieldType(value) {
|
|
89
|
-
if (value
|
|
300
|
+
if (isStringSetYMap(value)) return "stringset";
|
|
90
301
|
switch (typeof value) {
|
|
91
302
|
case "string":
|
|
92
303
|
return "string";
|
|
@@ -105,7 +316,10 @@ function encodeDefault(value) {
|
|
|
105
316
|
if (value === void 0 || value === null) return void 0;
|
|
106
317
|
if (typeof value === "function") {
|
|
107
318
|
const name = KNOWN_FUNCTION_DEFAULTS.get(value);
|
|
108
|
-
return name ? `$${name}` :
|
|
319
|
+
return name ? `$${name}` : UNKNOWN_FUNCTION_DEFAULT;
|
|
320
|
+
}
|
|
321
|
+
if (typeof value === "string" && value.startsWith("$")) {
|
|
322
|
+
return `$${value}`;
|
|
109
323
|
}
|
|
110
324
|
return value;
|
|
111
325
|
}
|
|
@@ -131,7 +345,7 @@ function syncModelMeta(yDoc, modelName, schema) {
|
|
|
131
345
|
if (compoundConstraints.length > 0) {
|
|
132
346
|
let constraints = meta.get("_constraints");
|
|
133
347
|
if (!constraints) {
|
|
134
|
-
constraints = new
|
|
348
|
+
constraints = new Y3.Map();
|
|
135
349
|
meta.set("_constraints", constraints);
|
|
136
350
|
}
|
|
137
351
|
for (const constraint of compoundConstraints) {
|
|
@@ -142,7 +356,7 @@ function syncModelMeta(yDoc, modelName, schema) {
|
|
|
142
356
|
if (relationships && Object.keys(relationships).length > 0) {
|
|
143
357
|
let rels = meta.get("_relationships");
|
|
144
358
|
if (!rels) {
|
|
145
|
-
rels = new
|
|
359
|
+
rels = new Y3.Map();
|
|
146
360
|
meta.set("_relationships", rels);
|
|
147
361
|
}
|
|
148
362
|
for (const [relName, relConfig] of Object.entries(relationships)) {
|
|
@@ -154,7 +368,7 @@ function syncModelMeta(yDoc, modelName, schema) {
|
|
|
154
368
|
function syncFieldMeta(metaMap, fieldName, fieldOpts) {
|
|
155
369
|
let fieldMeta = metaMap.get(fieldName);
|
|
156
370
|
if (!fieldMeta) {
|
|
157
|
-
fieldMeta = new
|
|
371
|
+
fieldMeta = new Y3.Map();
|
|
158
372
|
metaMap.set(fieldName, fieldMeta);
|
|
159
373
|
}
|
|
160
374
|
setIfChanged(fieldMeta, "type", fieldOpts.type);
|
|
@@ -162,6 +376,7 @@ function syncFieldMeta(metaMap, fieldName, fieldOpts) {
|
|
|
162
376
|
if (fieldOpts.unique) setIfChanged(fieldMeta, "unique", true);
|
|
163
377
|
if (fieldOpts.required) setIfChanged(fieldMeta, "required", true);
|
|
164
378
|
if (fieldOpts.autoAssign) setIfChanged(fieldMeta, "autoAssign", true);
|
|
379
|
+
if (fieldOpts.autoStamp) setIfChanged(fieldMeta, "autoStamp", fieldOpts.autoStamp);
|
|
165
380
|
if (fieldOpts.maxLength !== void 0) setIfChanged(fieldMeta, "maxLength", fieldOpts.maxLength);
|
|
166
381
|
if (fieldOpts.maxCount !== void 0) setIfChanged(fieldMeta, "maxCount", fieldOpts.maxCount);
|
|
167
382
|
const encoded = encodeDefault(fieldOpts.default);
|
|
@@ -170,7 +385,7 @@ function syncFieldMeta(metaMap, fieldName, fieldOpts) {
|
|
|
170
385
|
function syncConstraintMeta(constraintsMap, constraint) {
|
|
171
386
|
let cMeta = constraintsMap.get(constraint.name);
|
|
172
387
|
if (!cMeta) {
|
|
173
|
-
cMeta = new
|
|
388
|
+
cMeta = new Y3.Map();
|
|
174
389
|
constraintsMap.set(constraint.name, cMeta);
|
|
175
390
|
}
|
|
176
391
|
setIfChanged(cMeta, "type", "unique");
|
|
@@ -180,7 +395,7 @@ function syncConstraintMeta(constraintsMap, constraint) {
|
|
|
180
395
|
function syncRelationshipMeta(relsMap, relName, relConfig) {
|
|
181
396
|
let relMeta = relsMap.get(relName);
|
|
182
397
|
if (!relMeta) {
|
|
183
|
-
relMeta = new
|
|
398
|
+
relMeta = new Y3.Map();
|
|
184
399
|
relsMap.set(relName, relMeta);
|
|
185
400
|
}
|
|
186
401
|
for (const [key, value] of Object.entries(relConfig)) {
|
|
@@ -195,7 +410,7 @@ function syncInferredMeta(yDoc, modelName, recordData) {
|
|
|
195
410
|
if (fieldName.startsWith("_")) continue;
|
|
196
411
|
let fieldMeta = meta.get(fieldName);
|
|
197
412
|
if (!fieldMeta) {
|
|
198
|
-
fieldMeta = new
|
|
413
|
+
fieldMeta = new Y3.Map();
|
|
199
414
|
meta.set(fieldName, fieldMeta);
|
|
200
415
|
}
|
|
201
416
|
if (!fieldMeta.has("type")) {
|
|
@@ -211,32 +426,63 @@ function setIfChanged(map, key, value) {
|
|
|
211
426
|
map.set(key, value);
|
|
212
427
|
}
|
|
213
428
|
}
|
|
214
|
-
var
|
|
429
|
+
var Y3, KNOWN_FUNCTION_DEFAULTS, _syncedCache;
|
|
215
430
|
var init_metaSync = __esm({
|
|
216
431
|
"src/models/metaSync.ts"() {
|
|
217
432
|
"use strict";
|
|
218
|
-
|
|
433
|
+
Y3 = __toESM(require("yjs"), 1);
|
|
434
|
+
init_yjsValues();
|
|
435
|
+
init_writeLifecycle();
|
|
219
436
|
KNOWN_FUNCTION_DEFAULTS = /* @__PURE__ */ new WeakMap();
|
|
220
437
|
_syncedCache = /* @__PURE__ */ new WeakMap();
|
|
221
438
|
}
|
|
222
439
|
});
|
|
223
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
|
+
|
|
224
467
|
// src/models/BaseModel.ts
|
|
225
468
|
function generateULID() {
|
|
226
|
-
return (0,
|
|
469
|
+
return (0, import_ulid2.ulid)();
|
|
227
470
|
}
|
|
228
|
-
var
|
|
471
|
+
var Y5, import_ulid2, Logger;
|
|
229
472
|
var init_BaseModel = __esm({
|
|
230
473
|
"src/models/BaseModel.ts"() {
|
|
231
474
|
"use strict";
|
|
232
|
-
|
|
233
|
-
|
|
475
|
+
Y5 = __toESM(require("yjs"), 1);
|
|
476
|
+
import_ulid2 = require("ulid");
|
|
234
477
|
init_StringSet();
|
|
235
478
|
init_documentTypes();
|
|
236
479
|
init_DocumentQueryTranslator();
|
|
237
480
|
init_CursorManager();
|
|
238
481
|
init_sql();
|
|
239
482
|
init_metaSync();
|
|
483
|
+
init_writeLifecycle();
|
|
484
|
+
init_yjsValues();
|
|
485
|
+
init_uniqueIndex();
|
|
240
486
|
Logger = class {
|
|
241
487
|
static _logLevel = 1 /* ERROR */;
|
|
242
488
|
static _logCallback = null;
|
|
@@ -330,19 +576,36 @@ var init_ModelRegistry = __esm({
|
|
|
330
576
|
var cloudflare_exports = {};
|
|
331
577
|
__export(cloudflare_exports, {
|
|
332
578
|
DOClientEngine: () => DOClientEngine,
|
|
579
|
+
applyAutoStampsFromSchema: () => applyAutoStampsFromSchema,
|
|
580
|
+
applyDefaultsFromSchema: () => applyDefaultsFromSchema,
|
|
581
|
+
applyStringSetChange: () => applyStringSetChange,
|
|
582
|
+
applyStringSetDelta: () => applyStringSetDelta,
|
|
583
|
+
assertNever: () => assertNever,
|
|
584
|
+
buildUniqueKey: () => buildUniqueKey,
|
|
333
585
|
clearMetaSyncCache: () => clearMetaSyncCache,
|
|
334
586
|
connectDoDb: () => connectDoDb,
|
|
587
|
+
decodeFunctionDefault: () => decodeFunctionDefault,
|
|
335
588
|
discoverModelNames: () => discoverModelNames,
|
|
336
589
|
discoverSchema: () => discoverSchema,
|
|
590
|
+
ensureStringSetYMap: () => ensureStringSetYMap,
|
|
591
|
+
fieldUniqueConstraintName: () => fieldUniqueConstraintName,
|
|
592
|
+
fieldWriteKind: () => fieldWriteKind,
|
|
337
593
|
getActiveDOEngine: () => getActiveDOEngine,
|
|
338
594
|
inferFieldType: () => inferFieldType,
|
|
339
595
|
initJsBaoDO: () => initJsBaoDO,
|
|
596
|
+
isKnownFieldType: () => isKnownFieldType,
|
|
340
597
|
loadSchemaFromTomlString: () => loadSchemaFromTomlString,
|
|
598
|
+
parseStringSetOp: () => parseStringSetOp,
|
|
341
599
|
registerFunctionDefault: () => registerFunctionDefault,
|
|
600
|
+
registerFunctionDefaultGenerator: () => registerFunctionDefaultGenerator,
|
|
601
|
+
replaceStringSet: () => replaceStringSet,
|
|
342
602
|
resetJsBaoDO: () => resetJsBaoDO,
|
|
603
|
+
resolveDefaultValue: () => resolveDefaultValue,
|
|
343
604
|
schemaToToml: () => schemaToToml,
|
|
344
605
|
syncInferredMeta: () => syncInferredMeta,
|
|
345
|
-
syncModelMeta: () => syncModelMeta
|
|
606
|
+
syncModelMeta: () => syncModelMeta,
|
|
607
|
+
uniqueIndexMapName: () => uniqueIndexMapName,
|
|
608
|
+
writeField: () => writeField
|
|
346
609
|
});
|
|
347
610
|
module.exports = __toCommonJS(cloudflare_exports);
|
|
348
611
|
|
|
@@ -1223,7 +1486,8 @@ function connectDoDb(options) {
|
|
|
1223
1486
|
}
|
|
1224
1487
|
|
|
1225
1488
|
// src/utils/yDocSchema.ts
|
|
1226
|
-
var
|
|
1489
|
+
var Y6 = __toESM(require("yjs"), 1);
|
|
1490
|
+
init_yjsValues();
|
|
1227
1491
|
function discoverSchema(yDoc) {
|
|
1228
1492
|
const models = {};
|
|
1229
1493
|
const metaNames = /* @__PURE__ */ new Set();
|
|
@@ -1257,7 +1521,7 @@ function discoverModelNames(yDoc) {
|
|
|
1257
1521
|
function materializeMap(yDoc, key) {
|
|
1258
1522
|
try {
|
|
1259
1523
|
const map = yDoc.getMap(key);
|
|
1260
|
-
return map instanceof
|
|
1524
|
+
return map instanceof Y6.Map ? map : null;
|
|
1261
1525
|
} catch {
|
|
1262
1526
|
return null;
|
|
1263
1527
|
}
|
|
@@ -1267,11 +1531,11 @@ function readModelMeta(metaMap) {
|
|
|
1267
1531
|
let constraints;
|
|
1268
1532
|
let relationships;
|
|
1269
1533
|
for (const [key, value] of metaMap.entries()) {
|
|
1270
|
-
if (key === "_constraints" && value instanceof
|
|
1534
|
+
if (key === "_constraints" && value instanceof Y6.Map) {
|
|
1271
1535
|
constraints = readConstraints(value);
|
|
1272
|
-
} else if (key === "_relationships" && value instanceof
|
|
1536
|
+
} else if (key === "_relationships" && value instanceof Y6.Map) {
|
|
1273
1537
|
relationships = readRelationships(value);
|
|
1274
|
-
} else if (value instanceof
|
|
1538
|
+
} else if (value instanceof Y6.Map) {
|
|
1275
1539
|
fields[key] = readFieldMeta(value);
|
|
1276
1540
|
}
|
|
1277
1541
|
}
|
|
@@ -1290,6 +1554,10 @@ function readFieldMeta(fieldMap) {
|
|
|
1290
1554
|
if (fieldMap.get("unique") === true) field.unique = true;
|
|
1291
1555
|
if (fieldMap.get("required") === true) field.required = true;
|
|
1292
1556
|
if (fieldMap.get("autoAssign") === true) field.autoAssign = true;
|
|
1557
|
+
const autoStamp = fieldMap.get("autoStamp");
|
|
1558
|
+
if (typeof autoStamp === "string" && (autoStamp === "create" || autoStamp === "update" || autoStamp === "both")) {
|
|
1559
|
+
field.autoStamp = autoStamp;
|
|
1560
|
+
}
|
|
1293
1561
|
const def = fieldMap.get("default");
|
|
1294
1562
|
if (def !== void 0) field.default = def;
|
|
1295
1563
|
const maxLength = fieldMap.get("maxLength");
|
|
@@ -1302,7 +1570,7 @@ function inferModelFromData(dataMap) {
|
|
|
1302
1570
|
const fields = {};
|
|
1303
1571
|
let sampled = 0;
|
|
1304
1572
|
for (const [_recordId, recordValue] of dataMap.entries()) {
|
|
1305
|
-
if (!(recordValue instanceof
|
|
1573
|
+
if (!(recordValue instanceof Y6.Map)) continue;
|
|
1306
1574
|
if (++sampled > 5) break;
|
|
1307
1575
|
for (const [fieldName, value] of recordValue.entries()) {
|
|
1308
1576
|
if (fieldName.startsWith("_")) continue;
|
|
@@ -1315,7 +1583,7 @@ function inferModelFromData(dataMap) {
|
|
|
1315
1583
|
return { fields };
|
|
1316
1584
|
}
|
|
1317
1585
|
function inferTypeFromValue(value) {
|
|
1318
|
-
if (value
|
|
1586
|
+
if (isStringSetYMap(value)) return "stringset";
|
|
1319
1587
|
switch (typeof value) {
|
|
1320
1588
|
case "string":
|
|
1321
1589
|
return "string";
|
|
@@ -1330,7 +1598,7 @@ function inferTypeFromValue(value) {
|
|
|
1330
1598
|
function readConstraints(constraintsMap) {
|
|
1331
1599
|
const out = {};
|
|
1332
1600
|
for (const [name, value] of constraintsMap.entries()) {
|
|
1333
|
-
if (!(value instanceof
|
|
1601
|
+
if (!(value instanceof Y6.Map)) continue;
|
|
1334
1602
|
let fields = [];
|
|
1335
1603
|
const rawFields = value.get("fields");
|
|
1336
1604
|
if (typeof rawFields === "string") {
|
|
@@ -1349,7 +1617,7 @@ function readConstraints(constraintsMap) {
|
|
|
1349
1617
|
function readRelationships(relsMap) {
|
|
1350
1618
|
const out = {};
|
|
1351
1619
|
for (const [name, value] of relsMap.entries()) {
|
|
1352
|
-
if (!(value instanceof
|
|
1620
|
+
if (!(value instanceof Y6.Map)) continue;
|
|
1353
1621
|
const rel = {};
|
|
1354
1622
|
for (const [k, v] of value.entries()) {
|
|
1355
1623
|
rel[k] = v;
|
|
@@ -1360,6 +1628,7 @@ function readRelationships(relsMap) {
|
|
|
1360
1628
|
}
|
|
1361
1629
|
var CAMEL_TO_SNAKE = {
|
|
1362
1630
|
autoAssign: "auto_assign",
|
|
1631
|
+
autoStamp: "auto_stamp",
|
|
1363
1632
|
maxLength: "max_length",
|
|
1364
1633
|
maxCount: "max_count",
|
|
1365
1634
|
relatedIdField: "related_id_field",
|
|
@@ -1390,6 +1659,7 @@ function schemaToToml(schema) {
|
|
|
1390
1659
|
lines.push(`[models.${modelName}.fields.${fieldName}]`);
|
|
1391
1660
|
lines.push(`type = ${tomlValue(field.type)}`);
|
|
1392
1661
|
if (field.autoAssign) lines.push("auto_assign = true");
|
|
1662
|
+
if (field.autoStamp) lines.push(`auto_stamp = ${tomlValue(field.autoStamp)}`);
|
|
1393
1663
|
if (field.indexed) lines.push("indexed = true");
|
|
1394
1664
|
if (field.unique) lines.push("unique = true");
|
|
1395
1665
|
if (field.required) lines.push("required = true");
|
|
@@ -1426,6 +1696,7 @@ var import_smol_toml = require("smol-toml");
|
|
|
1426
1696
|
// src/models/schema.ts
|
|
1427
1697
|
init_BaseModel();
|
|
1428
1698
|
init_ModelRegistry();
|
|
1699
|
+
init_uniqueIndex();
|
|
1429
1700
|
function defineModelSchema(input) {
|
|
1430
1701
|
const { name, fields } = input;
|
|
1431
1702
|
const options = {
|
|
@@ -1468,7 +1739,7 @@ function resolveUniqueConstraints(modelName, fields, customConstraints) {
|
|
|
1468
1739
|
for (const [fieldName, options] of fields.entries()) {
|
|
1469
1740
|
if (options.unique) {
|
|
1470
1741
|
resolved.push({
|
|
1471
|
-
name:
|
|
1742
|
+
name: fieldUniqueConstraintName(modelName, fieldName),
|
|
1472
1743
|
fields: [fieldName]
|
|
1473
1744
|
});
|
|
1474
1745
|
}
|
|
@@ -1513,10 +1784,13 @@ var KNOWN_FIELD_KEYS = /* @__PURE__ */ new Set([
|
|
|
1513
1784
|
"unique",
|
|
1514
1785
|
"required",
|
|
1515
1786
|
"auto_assign",
|
|
1787
|
+
"auto_stamp",
|
|
1516
1788
|
"max_length",
|
|
1517
1789
|
"max_count",
|
|
1518
|
-
"default"
|
|
1790
|
+
"default",
|
|
1791
|
+
"enum"
|
|
1519
1792
|
]);
|
|
1793
|
+
var VALID_AUTO_STAMP_VALUES = /* @__PURE__ */ new Set(["create", "update", "both"]);
|
|
1520
1794
|
var KNOWN_MODEL_KEYS = /* @__PURE__ */ new Set([
|
|
1521
1795
|
"fields",
|
|
1522
1796
|
"relationships",
|
|
@@ -1558,9 +1832,37 @@ function parseFieldOptions(raw, context, strict) {
|
|
|
1558
1832
|
if (raw.unique === true) opts.unique = true;
|
|
1559
1833
|
if (raw.required === true) opts.required = true;
|
|
1560
1834
|
if (raw.auto_assign === true) opts.autoAssign = true;
|
|
1835
|
+
if (raw.auto_stamp !== void 0) {
|
|
1836
|
+
if (typeof raw.auto_stamp !== "string" || !VALID_AUTO_STAMP_VALUES.has(raw.auto_stamp)) {
|
|
1837
|
+
throw new Error(
|
|
1838
|
+
`${context}: invalid auto_stamp value "${raw.auto_stamp}". Must be one of: ${[
|
|
1839
|
+
...VALID_AUTO_STAMP_VALUES
|
|
1840
|
+
].join(", ")}`
|
|
1841
|
+
);
|
|
1842
|
+
}
|
|
1843
|
+
opts.autoStamp = raw.auto_stamp;
|
|
1844
|
+
}
|
|
1561
1845
|
if (raw.max_length !== void 0) opts.maxLength = raw.max_length;
|
|
1562
1846
|
if (raw.max_count !== void 0) opts.maxCount = raw.max_count;
|
|
1563
1847
|
if (raw.default !== void 0) opts.default = raw.default;
|
|
1848
|
+
if (raw.enum !== void 0) {
|
|
1849
|
+
if (raw.type !== "string") {
|
|
1850
|
+
throw new Error(
|
|
1851
|
+
`${context}: \`enum\` is only valid on a "string" field, not "${raw.type}".`
|
|
1852
|
+
);
|
|
1853
|
+
}
|
|
1854
|
+
if (!Array.isArray(raw.enum) || raw.enum.length === 0) {
|
|
1855
|
+
throw new Error(
|
|
1856
|
+
`${context}: \`enum\` must be a non-empty array of strings.`
|
|
1857
|
+
);
|
|
1858
|
+
}
|
|
1859
|
+
if (!raw.enum.every((v) => typeof v === "string")) {
|
|
1860
|
+
throw new Error(
|
|
1861
|
+
`${context}: \`enum\` values must all be strings.`
|
|
1862
|
+
);
|
|
1863
|
+
}
|
|
1864
|
+
opts.enum = [...raw.enum];
|
|
1865
|
+
}
|
|
1564
1866
|
return opts;
|
|
1565
1867
|
}
|
|
1566
1868
|
function requireField(raw, field, context) {
|
|
@@ -1683,4 +1985,6 @@ function loadSchemaFromTomlString(tomlString, options = {}) {
|
|
|
1683
1985
|
}
|
|
1684
1986
|
|
|
1685
1987
|
// src/cloudflare.ts
|
|
1988
|
+
init_uniqueIndex();
|
|
1686
1989
|
init_metaSync();
|
|
1990
|
+
init_writeLifecycle();
|