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.
@@ -57,10 +57,220 @@ var init_DocumentQueryTranslator = __esm({
57
57
  }
58
58
  });
59
59
 
60
- // src/models/metaSync.ts
60
+ // src/utils/yjsValues.ts
61
61
  import * as Y from "yjs";
62
+ function isStringSetYMap(value) {
63
+ if (!(value instanceof Y.Map)) return false;
64
+ for (const v of value.values()) {
65
+ if (v !== true) return false;
66
+ }
67
+ return true;
68
+ }
69
+ var init_yjsValues = __esm({
70
+ "src/utils/yjsValues.ts"() {
71
+ "use strict";
72
+ }
73
+ });
74
+
75
+ // src/models/writeLifecycle.ts
76
+ import * as Y2 from "yjs";
77
+ import { ulid } from "ulid";
78
+ function assertNever(x) {
79
+ throw new Error(`Unhandled field type: ${String(x)}`);
80
+ }
81
+ function fieldWriteKind(type) {
82
+ switch (type) {
83
+ case "string":
84
+ case "number":
85
+ case "boolean":
86
+ case "date":
87
+ case "id":
88
+ return "scalar";
89
+ case "stringset":
90
+ return "stringset";
91
+ default:
92
+ return assertNever(type);
93
+ }
94
+ }
95
+ function isKnownFieldType(type) {
96
+ return KNOWN_FIELD_TYPES.has(type);
97
+ }
98
+ function ensureStringSetYMap(rm, fieldName) {
99
+ const nested = rm.get(fieldName);
100
+ if (nested instanceof Y2.Map) return nested;
101
+ const fresh = new Y2.Map();
102
+ if (nested && typeof nested === "object") {
103
+ for (const [member, marker] of Object.entries(
104
+ nested
105
+ )) {
106
+ if (Boolean(marker)) fresh.set(member, true);
107
+ }
108
+ }
109
+ rm.set(fieldName, fresh);
110
+ return fresh;
111
+ }
112
+ function applyStringSetDelta(target, delta) {
113
+ if (delta.clear) {
114
+ for (const member of Array.from(target.keys())) target.delete(member);
115
+ }
116
+ if (delta.remove) {
117
+ for (const member of delta.remove) target.delete(String(member));
118
+ }
119
+ if (delta.add) {
120
+ for (const member of delta.add) {
121
+ const key = String(member);
122
+ if (target.get(key) !== true) target.set(key, true);
123
+ }
124
+ }
125
+ }
126
+ function replaceStringSet(rm, fieldName, members) {
127
+ const target = ensureStringSetYMap(rm, fieldName);
128
+ const desired = /* @__PURE__ */ new Set();
129
+ for (const member of members) desired.add(String(member));
130
+ for (const existing of Array.from(target.keys())) {
131
+ if (!desired.has(existing)) target.delete(existing);
132
+ }
133
+ for (const member of desired) {
134
+ if (target.get(member) !== true) target.set(member, true);
135
+ }
136
+ }
137
+ function applyStringSetChange(recordYMap, fieldName, change) {
138
+ const target = ensureStringSetYMap(recordYMap, fieldName);
139
+ applyStringSetDelta(target, {
140
+ add: change.additions,
141
+ remove: change.removals
142
+ });
143
+ }
144
+ function parseStringSetOp(value) {
145
+ if (value === null || typeof value !== "object" || Array.isArray(value) || value instanceof Y2.AbstractType) {
146
+ return null;
147
+ }
148
+ const keys = Object.keys(value);
149
+ const opKeys = keys.filter((k) => k.startsWith("$"));
150
+ if (opKeys.length === 0) return null;
151
+ const known = /* @__PURE__ */ new Set(["$add", "$remove", "$clear"]);
152
+ const unknown = keys.filter((k) => !known.has(k));
153
+ if (unknown.length > 0) {
154
+ throw new Error(
155
+ `Invalid stringset op: unexpected key(s) [${unknown.join(", ")}]. Only $add, $remove and $clear are supported.`
156
+ );
157
+ }
158
+ const obj = value;
159
+ const toMembers = (raw, opName) => {
160
+ if (raw === void 0) return [];
161
+ if (!Array.isArray(raw)) {
162
+ throw new Error(`Invalid stringset op: ${opName} must be an array.`);
163
+ }
164
+ return raw.map((m) => String(m));
165
+ };
166
+ return {
167
+ add: toMembers(obj.$add, "$add"),
168
+ remove: toMembers(obj.$remove, "$remove"),
169
+ clear: obj.$clear === true
170
+ };
171
+ }
172
+ function writeField(rm, declaredType, key, value, modelName) {
173
+ const kind = declaredType && isKnownFieldType(declaredType) ? fieldWriteKind(declaredType) : "scalar";
174
+ if (Array.isArray(value)) {
175
+ if (kind !== "stringset") {
176
+ throw new Error(
177
+ `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.`
178
+ );
179
+ }
180
+ replaceStringSet(rm, key, value);
181
+ return;
182
+ }
183
+ const op = parseStringSetOp(value);
184
+ if (op) {
185
+ if (kind !== "stringset") {
186
+ throw new Error(
187
+ `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}).`
188
+ );
189
+ }
190
+ applyStringSetDelta(ensureStringSetYMap(rm, key), op);
191
+ return;
192
+ }
193
+ if (kind === "stringset") {
194
+ throw new Error(
195
+ `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}.`
196
+ );
197
+ }
198
+ rm.set(key, value);
199
+ }
200
+ function registerFunctionDefaultGenerator(name, fn) {
201
+ FUNCTION_DEFAULT_GENERATORS.set(name, fn);
202
+ }
203
+ function decodeFunctionDefault(name) {
204
+ return FUNCTION_DEFAULT_GENERATORS.get(name);
205
+ }
206
+ function resolveDefaultValue(rawDefault, opts = {}) {
207
+ if (typeof rawDefault === "function") return rawDefault();
208
+ if (typeof rawDefault === "string" && rawDefault.startsWith("$")) {
209
+ if (rawDefault.startsWith("$$")) return rawDefault.slice(1);
210
+ const name = rawDefault.slice(1);
211
+ const gen = opts.decode?.(name) ?? decodeFunctionDefault(name);
212
+ if (!gen) {
213
+ throw new Error(
214
+ `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.`
215
+ );
216
+ }
217
+ return gen();
218
+ }
219
+ return rawDefault;
220
+ }
221
+ function applyDefaultsFromSchema(fields, data, opts = {}) {
222
+ for (const [fieldName, field] of Object.entries(fields)) {
223
+ if (fieldName === "id") continue;
224
+ if (!field || field.default === void 0) continue;
225
+ if (field.default === UNKNOWN_FUNCTION_DEFAULT) {
226
+ continue;
227
+ }
228
+ if (Object.prototype.hasOwnProperty.call(data, fieldName) && data[fieldName] !== void 0) {
229
+ continue;
230
+ }
231
+ data[fieldName] = resolveDefaultValue(field.default, {
232
+ fieldName,
233
+ modelName: opts.modelName,
234
+ decode: opts.decodeFunctionDefault
235
+ });
236
+ }
237
+ return data;
238
+ }
239
+ function applyAutoStampsFromSchema(fields, data, opts) {
240
+ const { isNew, now } = opts;
241
+ for (const [fieldName, field] of Object.entries(fields)) {
242
+ const stamp = field?.autoStamp;
243
+ if (!stamp) continue;
244
+ const explicit = Object.prototype.hasOwnProperty.call(data, fieldName) && data[fieldName] !== null && data[fieldName] !== void 0;
245
+ if (explicit) continue;
246
+ if (stamp === "create" && !isNew) continue;
247
+ data[fieldName] = now;
248
+ }
249
+ return data;
250
+ }
251
+ var KNOWN_FIELD_TYPE_MAP, KNOWN_FIELD_TYPES, FUNCTION_DEFAULT_GENERATORS, UNKNOWN_FUNCTION_DEFAULT;
252
+ var init_writeLifecycle = __esm({
253
+ "src/models/writeLifecycle.ts"() {
254
+ "use strict";
255
+ KNOWN_FIELD_TYPE_MAP = {
256
+ string: true,
257
+ number: true,
258
+ boolean: true,
259
+ date: true,
260
+ id: true,
261
+ stringset: true
262
+ };
263
+ KNOWN_FIELD_TYPES = new Set(Object.keys(KNOWN_FIELD_TYPE_MAP));
264
+ FUNCTION_DEFAULT_GENERATORS = /* @__PURE__ */ new Map();
265
+ registerFunctionDefaultGenerator("generate_ulid", () => ulid());
266
+ UNKNOWN_FUNCTION_DEFAULT = "$unknown_function";
267
+ }
268
+ });
269
+
270
+ // src/models/metaSync.ts
271
+ import * as Y3 from "yjs";
62
272
  function inferFieldType(value) {
63
- if (value instanceof Y.Map) return "stringset";
273
+ if (isStringSetYMap(value)) return "stringset";
64
274
  switch (typeof value) {
65
275
  case "string":
66
276
  return "string";
@@ -79,7 +289,10 @@ function encodeDefault(value) {
79
289
  if (value === void 0 || value === null) return void 0;
80
290
  if (typeof value === "function") {
81
291
  const name = KNOWN_FUNCTION_DEFAULTS.get(value);
82
- return name ? `$${name}` : "$unknown_function";
292
+ return name ? `$${name}` : UNKNOWN_FUNCTION_DEFAULT;
293
+ }
294
+ if (typeof value === "string" && value.startsWith("$")) {
295
+ return `$${value}`;
83
296
  }
84
297
  return value;
85
298
  }
@@ -105,7 +318,7 @@ function syncModelMeta(yDoc, modelName, schema) {
105
318
  if (compoundConstraints.length > 0) {
106
319
  let constraints = meta.get("_constraints");
107
320
  if (!constraints) {
108
- constraints = new Y.Map();
321
+ constraints = new Y3.Map();
109
322
  meta.set("_constraints", constraints);
110
323
  }
111
324
  for (const constraint of compoundConstraints) {
@@ -116,7 +329,7 @@ function syncModelMeta(yDoc, modelName, schema) {
116
329
  if (relationships && Object.keys(relationships).length > 0) {
117
330
  let rels = meta.get("_relationships");
118
331
  if (!rels) {
119
- rels = new Y.Map();
332
+ rels = new Y3.Map();
120
333
  meta.set("_relationships", rels);
121
334
  }
122
335
  for (const [relName, relConfig] of Object.entries(relationships)) {
@@ -128,7 +341,7 @@ function syncModelMeta(yDoc, modelName, schema) {
128
341
  function syncFieldMeta(metaMap, fieldName, fieldOpts) {
129
342
  let fieldMeta = metaMap.get(fieldName);
130
343
  if (!fieldMeta) {
131
- fieldMeta = new Y.Map();
344
+ fieldMeta = new Y3.Map();
132
345
  metaMap.set(fieldName, fieldMeta);
133
346
  }
134
347
  setIfChanged(fieldMeta, "type", fieldOpts.type);
@@ -136,6 +349,7 @@ function syncFieldMeta(metaMap, fieldName, fieldOpts) {
136
349
  if (fieldOpts.unique) setIfChanged(fieldMeta, "unique", true);
137
350
  if (fieldOpts.required) setIfChanged(fieldMeta, "required", true);
138
351
  if (fieldOpts.autoAssign) setIfChanged(fieldMeta, "autoAssign", true);
352
+ if (fieldOpts.autoStamp) setIfChanged(fieldMeta, "autoStamp", fieldOpts.autoStamp);
139
353
  if (fieldOpts.maxLength !== void 0) setIfChanged(fieldMeta, "maxLength", fieldOpts.maxLength);
140
354
  if (fieldOpts.maxCount !== void 0) setIfChanged(fieldMeta, "maxCount", fieldOpts.maxCount);
141
355
  const encoded = encodeDefault(fieldOpts.default);
@@ -144,7 +358,7 @@ function syncFieldMeta(metaMap, fieldName, fieldOpts) {
144
358
  function syncConstraintMeta(constraintsMap, constraint) {
145
359
  let cMeta = constraintsMap.get(constraint.name);
146
360
  if (!cMeta) {
147
- cMeta = new Y.Map();
361
+ cMeta = new Y3.Map();
148
362
  constraintsMap.set(constraint.name, cMeta);
149
363
  }
150
364
  setIfChanged(cMeta, "type", "unique");
@@ -154,7 +368,7 @@ function syncConstraintMeta(constraintsMap, constraint) {
154
368
  function syncRelationshipMeta(relsMap, relName, relConfig) {
155
369
  let relMeta = relsMap.get(relName);
156
370
  if (!relMeta) {
157
- relMeta = new Y.Map();
371
+ relMeta = new Y3.Map();
158
372
  relsMap.set(relName, relMeta);
159
373
  }
160
374
  for (const [key, value] of Object.entries(relConfig)) {
@@ -169,7 +383,7 @@ function syncInferredMeta(yDoc, modelName, recordData) {
169
383
  if (fieldName.startsWith("_")) continue;
170
384
  let fieldMeta = meta.get(fieldName);
171
385
  if (!fieldMeta) {
172
- fieldMeta = new Y.Map();
386
+ fieldMeta = new Y3.Map();
173
387
  meta.set(fieldName, fieldMeta);
174
388
  }
175
389
  if (!fieldMeta.has("type")) {
@@ -189,16 +403,43 @@ var KNOWN_FUNCTION_DEFAULTS, _syncedCache;
189
403
  var init_metaSync = __esm({
190
404
  "src/models/metaSync.ts"() {
191
405
  "use strict";
406
+ init_yjsValues();
407
+ init_writeLifecycle();
192
408
  KNOWN_FUNCTION_DEFAULTS = /* @__PURE__ */ new WeakMap();
193
409
  _syncedCache = /* @__PURE__ */ new WeakMap();
194
410
  }
195
411
  });
196
412
 
413
+ // src/utils/uniqueIndex.ts
414
+ import * as Y4 from "yjs";
415
+ function buildUniqueKey(recordData, fields) {
416
+ const keyParts = [];
417
+ for (const field of fields) {
418
+ const value = recordData instanceof Y4.Map ? recordData.get(field) : recordData[field];
419
+ if (value === null || value === void 0) {
420
+ return null;
421
+ }
422
+ keyParts.push(String(value));
423
+ }
424
+ return keyParts.join("|");
425
+ }
426
+ function uniqueIndexMapName(modelName, constraintName) {
427
+ return `_uniqueIdx_${modelName}_${constraintName}`;
428
+ }
429
+ function fieldUniqueConstraintName(modelName, fieldName) {
430
+ return `${modelName}_${fieldName}_unique`;
431
+ }
432
+ var init_uniqueIndex = __esm({
433
+ "src/utils/uniqueIndex.ts"() {
434
+ "use strict";
435
+ }
436
+ });
437
+
197
438
  // src/models/BaseModel.ts
198
- import * as Y2 from "yjs";
199
- import { ulid } from "ulid";
439
+ import * as Y5 from "yjs";
440
+ import { ulid as ulid2 } from "ulid";
200
441
  function generateULID() {
201
- return ulid();
442
+ return ulid2();
202
443
  }
203
444
  var Logger;
204
445
  var init_BaseModel = __esm({
@@ -210,6 +451,9 @@ var init_BaseModel = __esm({
210
451
  init_CursorManager();
211
452
  init_sql();
212
453
  init_metaSync();
454
+ init_writeLifecycle();
455
+ init_yjsValues();
456
+ init_uniqueIndex();
213
457
  Logger = class {
214
458
  static _logLevel = 1 /* ERROR */;
215
459
  static _logCallback = null;
@@ -1176,7 +1420,8 @@ function connectDoDb(options) {
1176
1420
  }
1177
1421
 
1178
1422
  // src/utils/yDocSchema.ts
1179
- import * as Y3 from "yjs";
1423
+ init_yjsValues();
1424
+ import * as Y6 from "yjs";
1180
1425
  function discoverSchema(yDoc) {
1181
1426
  const models = {};
1182
1427
  const metaNames = /* @__PURE__ */ new Set();
@@ -1210,7 +1455,7 @@ function discoverModelNames(yDoc) {
1210
1455
  function materializeMap(yDoc, key) {
1211
1456
  try {
1212
1457
  const map = yDoc.getMap(key);
1213
- return map instanceof Y3.Map ? map : null;
1458
+ return map instanceof Y6.Map ? map : null;
1214
1459
  } catch {
1215
1460
  return null;
1216
1461
  }
@@ -1220,11 +1465,11 @@ function readModelMeta(metaMap) {
1220
1465
  let constraints;
1221
1466
  let relationships;
1222
1467
  for (const [key, value] of metaMap.entries()) {
1223
- if (key === "_constraints" && value instanceof Y3.Map) {
1468
+ if (key === "_constraints" && value instanceof Y6.Map) {
1224
1469
  constraints = readConstraints(value);
1225
- } else if (key === "_relationships" && value instanceof Y3.Map) {
1470
+ } else if (key === "_relationships" && value instanceof Y6.Map) {
1226
1471
  relationships = readRelationships(value);
1227
- } else if (value instanceof Y3.Map) {
1472
+ } else if (value instanceof Y6.Map) {
1228
1473
  fields[key] = readFieldMeta(value);
1229
1474
  }
1230
1475
  }
@@ -1243,6 +1488,10 @@ function readFieldMeta(fieldMap) {
1243
1488
  if (fieldMap.get("unique") === true) field.unique = true;
1244
1489
  if (fieldMap.get("required") === true) field.required = true;
1245
1490
  if (fieldMap.get("autoAssign") === true) field.autoAssign = true;
1491
+ const autoStamp = fieldMap.get("autoStamp");
1492
+ if (typeof autoStamp === "string" && (autoStamp === "create" || autoStamp === "update" || autoStamp === "both")) {
1493
+ field.autoStamp = autoStamp;
1494
+ }
1246
1495
  const def = fieldMap.get("default");
1247
1496
  if (def !== void 0) field.default = def;
1248
1497
  const maxLength = fieldMap.get("maxLength");
@@ -1255,7 +1504,7 @@ function inferModelFromData(dataMap) {
1255
1504
  const fields = {};
1256
1505
  let sampled = 0;
1257
1506
  for (const [_recordId, recordValue] of dataMap.entries()) {
1258
- if (!(recordValue instanceof Y3.Map)) continue;
1507
+ if (!(recordValue instanceof Y6.Map)) continue;
1259
1508
  if (++sampled > 5) break;
1260
1509
  for (const [fieldName, value] of recordValue.entries()) {
1261
1510
  if (fieldName.startsWith("_")) continue;
@@ -1268,7 +1517,7 @@ function inferModelFromData(dataMap) {
1268
1517
  return { fields };
1269
1518
  }
1270
1519
  function inferTypeFromValue(value) {
1271
- if (value instanceof Y3.Map) return "stringset";
1520
+ if (isStringSetYMap(value)) return "stringset";
1272
1521
  switch (typeof value) {
1273
1522
  case "string":
1274
1523
  return "string";
@@ -1283,7 +1532,7 @@ function inferTypeFromValue(value) {
1283
1532
  function readConstraints(constraintsMap) {
1284
1533
  const out = {};
1285
1534
  for (const [name, value] of constraintsMap.entries()) {
1286
- if (!(value instanceof Y3.Map)) continue;
1535
+ if (!(value instanceof Y6.Map)) continue;
1287
1536
  let fields = [];
1288
1537
  const rawFields = value.get("fields");
1289
1538
  if (typeof rawFields === "string") {
@@ -1302,7 +1551,7 @@ function readConstraints(constraintsMap) {
1302
1551
  function readRelationships(relsMap) {
1303
1552
  const out = {};
1304
1553
  for (const [name, value] of relsMap.entries()) {
1305
- if (!(value instanceof Y3.Map)) continue;
1554
+ if (!(value instanceof Y6.Map)) continue;
1306
1555
  const rel = {};
1307
1556
  for (const [k, v] of value.entries()) {
1308
1557
  rel[k] = v;
@@ -1313,6 +1562,7 @@ function readRelationships(relsMap) {
1313
1562
  }
1314
1563
  var CAMEL_TO_SNAKE = {
1315
1564
  autoAssign: "auto_assign",
1565
+ autoStamp: "auto_stamp",
1316
1566
  maxLength: "max_length",
1317
1567
  maxCount: "max_count",
1318
1568
  relatedIdField: "related_id_field",
@@ -1343,6 +1593,7 @@ function schemaToToml(schema) {
1343
1593
  lines.push(`[models.${modelName}.fields.${fieldName}]`);
1344
1594
  lines.push(`type = ${tomlValue(field.type)}`);
1345
1595
  if (field.autoAssign) lines.push("auto_assign = true");
1596
+ if (field.autoStamp) lines.push(`auto_stamp = ${tomlValue(field.autoStamp)}`);
1346
1597
  if (field.indexed) lines.push("indexed = true");
1347
1598
  if (field.unique) lines.push("unique = true");
1348
1599
  if (field.required) lines.push("required = true");
@@ -1379,6 +1630,7 @@ import { parse as parseToml } from "smol-toml";
1379
1630
  // src/models/schema.ts
1380
1631
  init_BaseModel();
1381
1632
  init_ModelRegistry();
1633
+ init_uniqueIndex();
1382
1634
  function defineModelSchema(input) {
1383
1635
  const { name, fields } = input;
1384
1636
  const options = {
@@ -1421,7 +1673,7 @@ function resolveUniqueConstraints(modelName, fields, customConstraints) {
1421
1673
  for (const [fieldName, options] of fields.entries()) {
1422
1674
  if (options.unique) {
1423
1675
  resolved.push({
1424
- name: `${modelName}_${fieldName}_unique`,
1676
+ name: fieldUniqueConstraintName(modelName, fieldName),
1425
1677
  fields: [fieldName]
1426
1678
  });
1427
1679
  }
@@ -1466,10 +1718,13 @@ var KNOWN_FIELD_KEYS = /* @__PURE__ */ new Set([
1466
1718
  "unique",
1467
1719
  "required",
1468
1720
  "auto_assign",
1721
+ "auto_stamp",
1469
1722
  "max_length",
1470
1723
  "max_count",
1471
- "default"
1724
+ "default",
1725
+ "enum"
1472
1726
  ]);
1727
+ var VALID_AUTO_STAMP_VALUES = /* @__PURE__ */ new Set(["create", "update", "both"]);
1473
1728
  var KNOWN_MODEL_KEYS = /* @__PURE__ */ new Set([
1474
1729
  "fields",
1475
1730
  "relationships",
@@ -1511,9 +1766,37 @@ function parseFieldOptions(raw, context, strict) {
1511
1766
  if (raw.unique === true) opts.unique = true;
1512
1767
  if (raw.required === true) opts.required = true;
1513
1768
  if (raw.auto_assign === true) opts.autoAssign = true;
1769
+ if (raw.auto_stamp !== void 0) {
1770
+ if (typeof raw.auto_stamp !== "string" || !VALID_AUTO_STAMP_VALUES.has(raw.auto_stamp)) {
1771
+ throw new Error(
1772
+ `${context}: invalid auto_stamp value "${raw.auto_stamp}". Must be one of: ${[
1773
+ ...VALID_AUTO_STAMP_VALUES
1774
+ ].join(", ")}`
1775
+ );
1776
+ }
1777
+ opts.autoStamp = raw.auto_stamp;
1778
+ }
1514
1779
  if (raw.max_length !== void 0) opts.maxLength = raw.max_length;
1515
1780
  if (raw.max_count !== void 0) opts.maxCount = raw.max_count;
1516
1781
  if (raw.default !== void 0) opts.default = raw.default;
1782
+ if (raw.enum !== void 0) {
1783
+ if (raw.type !== "string") {
1784
+ throw new Error(
1785
+ `${context}: \`enum\` is only valid on a "string" field, not "${raw.type}".`
1786
+ );
1787
+ }
1788
+ if (!Array.isArray(raw.enum) || raw.enum.length === 0) {
1789
+ throw new Error(
1790
+ `${context}: \`enum\` must be a non-empty array of strings.`
1791
+ );
1792
+ }
1793
+ if (!raw.enum.every((v) => typeof v === "string")) {
1794
+ throw new Error(
1795
+ `${context}: \`enum\` values must all be strings.`
1796
+ );
1797
+ }
1798
+ opts.enum = [...raw.enum];
1799
+ }
1517
1800
  return opts;
1518
1801
  }
1519
1802
  function requireField(raw, field, context) {
@@ -1636,20 +1919,39 @@ function loadSchemaFromTomlString(tomlString, options = {}) {
1636
1919
  }
1637
1920
 
1638
1921
  // src/cloudflare.ts
1922
+ init_uniqueIndex();
1639
1923
  init_metaSync();
1924
+ init_writeLifecycle();
1640
1925
  export {
1641
1926
  DOClientEngine,
1927
+ applyAutoStampsFromSchema,
1928
+ applyDefaultsFromSchema,
1929
+ applyStringSetChange,
1930
+ applyStringSetDelta,
1931
+ assertNever,
1932
+ buildUniqueKey,
1642
1933
  clearMetaSyncCache,
1643
1934
  connectDoDb,
1935
+ decodeFunctionDefault,
1644
1936
  discoverModelNames,
1645
1937
  discoverSchema,
1938
+ ensureStringSetYMap,
1939
+ fieldUniqueConstraintName,
1940
+ fieldWriteKind,
1646
1941
  getActiveDOEngine,
1647
1942
  inferFieldType,
1648
1943
  initJsBaoDO,
1944
+ isKnownFieldType,
1649
1945
  loadSchemaFromTomlString,
1946
+ parseStringSetOp,
1650
1947
  registerFunctionDefault,
1948
+ registerFunctionDefaultGenerator,
1949
+ replaceStringSet,
1651
1950
  resetJsBaoDO,
1951
+ resolveDefaultValue,
1652
1952
  schemaToToml,
1653
1953
  syncInferredMeta,
1654
- syncModelMeta
1954
+ syncModelMeta,
1955
+ uniqueIndexMapName,
1956
+ writeField
1655
1957
  };