js-bao 0.3.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser.cjs +367 -1
- package/dist/browser.d.cts +126 -1
- package/dist/browser.d.ts +126 -1
- package/dist/browser.js +367 -1
- package/dist/client.cjs +16 -11
- package/dist/client.d.cts +3 -1
- package/dist/client.d.ts +3 -1
- package/dist/client.js +16 -11
- package/dist/cloudflare-do.cjs +937 -286
- package/dist/cloudflare-do.d.cts +517 -15
- package/dist/cloudflare-do.d.ts +517 -15
- package/dist/cloudflare-do.js +928 -286
- package/dist/cloudflare.cjs +573 -18
- package/dist/cloudflare.d.cts +147 -2
- package/dist/cloudflare.d.ts +147 -2
- package/dist/cloudflare.js +573 -18
- package/dist/codegen.cjs +6 -6
- package/dist/index.cjs +19 -10
- package/dist/index.js +19 -10
- package/dist/node.cjs +388 -6
- package/dist/node.d.cts +131 -1
- package/dist/node.d.ts +131 -1
- package/dist/node.js +377 -5
- package/package.json +6 -6
package/dist/browser.cjs
CHANGED
|
@@ -1184,6 +1184,19 @@ var init_DocumentQueryTranslator = __esm({
|
|
|
1184
1184
|
});
|
|
1185
1185
|
|
|
1186
1186
|
// src/models/metaSync.ts
|
|
1187
|
+
function inferFieldType(value) {
|
|
1188
|
+
if (value instanceof Y.Map) return "stringset";
|
|
1189
|
+
switch (typeof value) {
|
|
1190
|
+
case "string":
|
|
1191
|
+
return "string";
|
|
1192
|
+
case "number":
|
|
1193
|
+
return "number";
|
|
1194
|
+
case "boolean":
|
|
1195
|
+
return "boolean";
|
|
1196
|
+
default:
|
|
1197
|
+
return null;
|
|
1198
|
+
}
|
|
1199
|
+
}
|
|
1187
1200
|
function registerFunctionDefault(fn, name) {
|
|
1188
1201
|
KNOWN_FUNCTION_DEFAULTS.set(fn, name);
|
|
1189
1202
|
}
|
|
@@ -1195,6 +1208,11 @@ function encodeDefault(value) {
|
|
|
1195
1208
|
}
|
|
1196
1209
|
return value;
|
|
1197
1210
|
}
|
|
1211
|
+
function clearMetaSyncCache(yDoc) {
|
|
1212
|
+
if (yDoc) {
|
|
1213
|
+
_syncedCache.delete(yDoc);
|
|
1214
|
+
}
|
|
1215
|
+
}
|
|
1198
1216
|
function syncModelMeta(yDoc, modelName, schema) {
|
|
1199
1217
|
let synced = _syncedCache.get(yDoc);
|
|
1200
1218
|
if (synced?.has(modelName)) return;
|
|
@@ -1270,6 +1288,23 @@ function syncRelationshipMeta(relsMap, relName, relConfig) {
|
|
|
1270
1288
|
}
|
|
1271
1289
|
}
|
|
1272
1290
|
}
|
|
1291
|
+
function syncInferredMeta(yDoc, modelName, recordData) {
|
|
1292
|
+
const meta = yDoc.getMap(`_meta_${modelName}`);
|
|
1293
|
+
for (const [fieldName, value] of Object.entries(recordData)) {
|
|
1294
|
+
if (fieldName.startsWith("_")) continue;
|
|
1295
|
+
let fieldMeta = meta.get(fieldName);
|
|
1296
|
+
if (!fieldMeta) {
|
|
1297
|
+
fieldMeta = new Y.Map();
|
|
1298
|
+
meta.set(fieldName, fieldMeta);
|
|
1299
|
+
}
|
|
1300
|
+
if (!fieldMeta.has("type")) {
|
|
1301
|
+
const inferredType = inferFieldType(value);
|
|
1302
|
+
if (inferredType) {
|
|
1303
|
+
fieldMeta.set("type", inferredType);
|
|
1304
|
+
}
|
|
1305
|
+
}
|
|
1306
|
+
}
|
|
1307
|
+
}
|
|
1273
1308
|
function setIfChanged(map, key, value) {
|
|
1274
1309
|
if (map.get(key) !== value) {
|
|
1275
1310
|
map.set(key, value);
|
|
@@ -5515,15 +5550,24 @@ __export(browser_exports, {
|
|
|
5515
5550
|
attachAndRegisterModel: () => attachAndRegisterModel,
|
|
5516
5551
|
attachSchemaToClass: () => attachSchemaToClass,
|
|
5517
5552
|
autoRegisterModel: () => autoRegisterModel,
|
|
5553
|
+
clearMetaSyncCache: () => clearMetaSyncCache,
|
|
5518
5554
|
createModelClass: () => createModelClass,
|
|
5519
5555
|
defineModelSchema: () => defineModelSchema,
|
|
5520
5556
|
detectEnvironment: () => detectEnvironment,
|
|
5557
|
+
discoverModelNames: () => discoverModelNames,
|
|
5558
|
+
discoverSchema: () => discoverSchema,
|
|
5521
5559
|
features: () => features,
|
|
5522
5560
|
generateULID: () => generateULID,
|
|
5561
|
+
inferFieldType: () => inferFieldType,
|
|
5523
5562
|
initJsBao: () => initJsBao,
|
|
5524
5563
|
isBrowser: () => isBrowser,
|
|
5525
5564
|
isNode: () => isNode,
|
|
5526
|
-
|
|
5565
|
+
loadSchemaFromTomlString: () => loadSchemaFromTomlString,
|
|
5566
|
+
registerFunctionDefault: () => registerFunctionDefault,
|
|
5567
|
+
resetJsBao: () => resetJsBao,
|
|
5568
|
+
schemaToToml: () => schemaToToml,
|
|
5569
|
+
syncInferredMeta: () => syncInferredMeta,
|
|
5570
|
+
syncModelMeta: () => syncModelMeta
|
|
5527
5571
|
});
|
|
5528
5572
|
module.exports = __toCommonJS(browser_exports);
|
|
5529
5573
|
init_BaseModel();
|
|
@@ -6560,3 +6604,325 @@ function attachAndRegisterModel(modelClass, schema) {
|
|
|
6560
6604
|
const runtimeShape = attachSchemaToClass(modelClass, schema);
|
|
6561
6605
|
autoRegisterModel(modelClass, runtimeShape);
|
|
6562
6606
|
}
|
|
6607
|
+
|
|
6608
|
+
// src/utils/yDocSchema.ts
|
|
6609
|
+
var Y3 = __toESM(require("yjs"), 1);
|
|
6610
|
+
function discoverSchema(yDoc) {
|
|
6611
|
+
const models = {};
|
|
6612
|
+
const metaNames = /* @__PURE__ */ new Set();
|
|
6613
|
+
for (const key of yDoc.share.keys()) {
|
|
6614
|
+
if (!key.startsWith("_meta_")) continue;
|
|
6615
|
+
const map = materializeMap(yDoc, key);
|
|
6616
|
+
if (!map) continue;
|
|
6617
|
+
const modelName = key.slice("_meta_".length);
|
|
6618
|
+
metaNames.add(modelName);
|
|
6619
|
+
models[modelName] = readModelMeta(map);
|
|
6620
|
+
}
|
|
6621
|
+
for (const key of yDoc.share.keys()) {
|
|
6622
|
+
if (key.startsWith("_")) continue;
|
|
6623
|
+
if (metaNames.has(key)) continue;
|
|
6624
|
+
const map = materializeMap(yDoc, key);
|
|
6625
|
+
if (!map || map.size === 0) continue;
|
|
6626
|
+
const inferred = inferModelFromData(map);
|
|
6627
|
+
if (inferred) models[key] = inferred;
|
|
6628
|
+
}
|
|
6629
|
+
return { models };
|
|
6630
|
+
}
|
|
6631
|
+
function discoverModelNames(yDoc) {
|
|
6632
|
+
const names = [];
|
|
6633
|
+
for (const key of yDoc.share.keys()) {
|
|
6634
|
+
if (key.startsWith("_")) continue;
|
|
6635
|
+
const map = materializeMap(yDoc, key);
|
|
6636
|
+
if (map) names.push(key);
|
|
6637
|
+
}
|
|
6638
|
+
return names.sort();
|
|
6639
|
+
}
|
|
6640
|
+
function materializeMap(yDoc, key) {
|
|
6641
|
+
try {
|
|
6642
|
+
const map = yDoc.getMap(key);
|
|
6643
|
+
return map instanceof Y3.Map ? map : null;
|
|
6644
|
+
} catch {
|
|
6645
|
+
return null;
|
|
6646
|
+
}
|
|
6647
|
+
}
|
|
6648
|
+
function readModelMeta(metaMap) {
|
|
6649
|
+
const fields = {};
|
|
6650
|
+
let constraints;
|
|
6651
|
+
let relationships;
|
|
6652
|
+
for (const [key, value] of metaMap.entries()) {
|
|
6653
|
+
if (key === "_constraints" && value instanceof Y3.Map) {
|
|
6654
|
+
constraints = readConstraints(value);
|
|
6655
|
+
} else if (key === "_relationships" && value instanceof Y3.Map) {
|
|
6656
|
+
relationships = readRelationships(value);
|
|
6657
|
+
} else if (value instanceof Y3.Map) {
|
|
6658
|
+
fields[key] = readFieldMeta(value);
|
|
6659
|
+
}
|
|
6660
|
+
}
|
|
6661
|
+
const model = { fields };
|
|
6662
|
+
if (constraints && Object.keys(constraints).length > 0) {
|
|
6663
|
+
model.constraints = constraints;
|
|
6664
|
+
}
|
|
6665
|
+
if (relationships && Object.keys(relationships).length > 0) {
|
|
6666
|
+
model.relationships = relationships;
|
|
6667
|
+
}
|
|
6668
|
+
return model;
|
|
6669
|
+
}
|
|
6670
|
+
function readFieldMeta(fieldMap) {
|
|
6671
|
+
const field = { type: fieldMap.get("type") ?? "unknown" };
|
|
6672
|
+
if (fieldMap.get("indexed") === true) field.indexed = true;
|
|
6673
|
+
if (fieldMap.get("unique") === true) field.unique = true;
|
|
6674
|
+
if (fieldMap.get("required") === true) field.required = true;
|
|
6675
|
+
if (fieldMap.get("autoAssign") === true) field.autoAssign = true;
|
|
6676
|
+
const def = fieldMap.get("default");
|
|
6677
|
+
if (def !== void 0) field.default = def;
|
|
6678
|
+
const maxLength = fieldMap.get("maxLength");
|
|
6679
|
+
if (maxLength !== void 0) field.maxLength = maxLength;
|
|
6680
|
+
const maxCount = fieldMap.get("maxCount");
|
|
6681
|
+
if (maxCount !== void 0) field.maxCount = maxCount;
|
|
6682
|
+
return field;
|
|
6683
|
+
}
|
|
6684
|
+
function inferModelFromData(dataMap) {
|
|
6685
|
+
const fields = {};
|
|
6686
|
+
let sampled = 0;
|
|
6687
|
+
for (const [_recordId, recordValue] of dataMap.entries()) {
|
|
6688
|
+
if (!(recordValue instanceof Y3.Map)) continue;
|
|
6689
|
+
if (++sampled > 5) break;
|
|
6690
|
+
for (const [fieldName, value] of recordValue.entries()) {
|
|
6691
|
+
if (fieldName.startsWith("_")) continue;
|
|
6692
|
+
if (fields[fieldName]) continue;
|
|
6693
|
+
const type = inferTypeFromValue(value);
|
|
6694
|
+
if (type) fields[fieldName] = { type };
|
|
6695
|
+
}
|
|
6696
|
+
}
|
|
6697
|
+
if (Object.keys(fields).length === 0) return null;
|
|
6698
|
+
return { fields };
|
|
6699
|
+
}
|
|
6700
|
+
function inferTypeFromValue(value) {
|
|
6701
|
+
if (value instanceof Y3.Map) return "stringset";
|
|
6702
|
+
switch (typeof value) {
|
|
6703
|
+
case "string":
|
|
6704
|
+
return "string";
|
|
6705
|
+
case "number":
|
|
6706
|
+
return "number";
|
|
6707
|
+
case "boolean":
|
|
6708
|
+
return "boolean";
|
|
6709
|
+
default:
|
|
6710
|
+
return null;
|
|
6711
|
+
}
|
|
6712
|
+
}
|
|
6713
|
+
function readConstraints(constraintsMap) {
|
|
6714
|
+
const out = {};
|
|
6715
|
+
for (const [name, value] of constraintsMap.entries()) {
|
|
6716
|
+
if (!(value instanceof Y3.Map)) continue;
|
|
6717
|
+
let fields = [];
|
|
6718
|
+
const rawFields = value.get("fields");
|
|
6719
|
+
if (typeof rawFields === "string") {
|
|
6720
|
+
try {
|
|
6721
|
+
fields = JSON.parse(rawFields);
|
|
6722
|
+
} catch {
|
|
6723
|
+
}
|
|
6724
|
+
}
|
|
6725
|
+
out[name] = {
|
|
6726
|
+
type: value.get("type") ?? "unknown",
|
|
6727
|
+
fields
|
|
6728
|
+
};
|
|
6729
|
+
}
|
|
6730
|
+
return out;
|
|
6731
|
+
}
|
|
6732
|
+
function readRelationships(relsMap) {
|
|
6733
|
+
const out = {};
|
|
6734
|
+
for (const [name, value] of relsMap.entries()) {
|
|
6735
|
+
if (!(value instanceof Y3.Map)) continue;
|
|
6736
|
+
const rel = {};
|
|
6737
|
+
for (const [k, v] of value.entries()) {
|
|
6738
|
+
rel[k] = v;
|
|
6739
|
+
}
|
|
6740
|
+
out[name] = rel;
|
|
6741
|
+
}
|
|
6742
|
+
return out;
|
|
6743
|
+
}
|
|
6744
|
+
var CAMEL_TO_SNAKE = {
|
|
6745
|
+
autoAssign: "auto_assign",
|
|
6746
|
+
maxLength: "max_length",
|
|
6747
|
+
maxCount: "max_count",
|
|
6748
|
+
relatedIdField: "related_id_field",
|
|
6749
|
+
joinModel: "join_model",
|
|
6750
|
+
joinModelLocalField: "join_model_local_field",
|
|
6751
|
+
joinModelRelatedField: "join_model_related_field",
|
|
6752
|
+
joinModelOrderByField: "join_model_order_by_field",
|
|
6753
|
+
joinModelOrderDirection: "join_model_order_direction",
|
|
6754
|
+
orderByField: "order_by_field",
|
|
6755
|
+
orderDirection: "order_direction"
|
|
6756
|
+
};
|
|
6757
|
+
function toSnake(key) {
|
|
6758
|
+
return CAMEL_TO_SNAKE[key] ?? key;
|
|
6759
|
+
}
|
|
6760
|
+
function tomlValue(v) {
|
|
6761
|
+
if (typeof v === "string") {
|
|
6762
|
+
return `"${v.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/\t/g, "\\t")}"`;
|
|
6763
|
+
}
|
|
6764
|
+
return String(v);
|
|
6765
|
+
}
|
|
6766
|
+
function schemaToToml(schema) {
|
|
6767
|
+
const lines = [];
|
|
6768
|
+
for (const [modelName, model] of Object.entries(schema.models)) {
|
|
6769
|
+
if (lines.length > 0) lines.push("", "");
|
|
6770
|
+
lines.push(`[models.${modelName}]`);
|
|
6771
|
+
for (const [fieldName, field] of Object.entries(model.fields)) {
|
|
6772
|
+
lines.push("");
|
|
6773
|
+
lines.push(`[models.${modelName}.fields.${fieldName}]`);
|
|
6774
|
+
lines.push(`type = ${tomlValue(field.type)}`);
|
|
6775
|
+
if (field.autoAssign) lines.push("auto_assign = true");
|
|
6776
|
+
if (field.indexed) lines.push("indexed = true");
|
|
6777
|
+
if (field.unique) lines.push("unique = true");
|
|
6778
|
+
if (field.required) lines.push("required = true");
|
|
6779
|
+
if (field.maxLength !== void 0) lines.push(`max_length = ${field.maxLength}`);
|
|
6780
|
+
if (field.maxCount !== void 0) lines.push(`max_count = ${field.maxCount}`);
|
|
6781
|
+
if (field.default !== void 0) lines.push(`default = ${tomlValue(field.default)}`);
|
|
6782
|
+
}
|
|
6783
|
+
if (model.relationships) {
|
|
6784
|
+
for (const [relName, rel] of Object.entries(model.relationships)) {
|
|
6785
|
+
lines.push("");
|
|
6786
|
+
lines.push(`[models.${modelName}.relationships.${relName}]`);
|
|
6787
|
+
for (const [k, v] of Object.entries(rel)) {
|
|
6788
|
+
if (v === void 0) continue;
|
|
6789
|
+
lines.push(`${toSnake(k)} = ${tomlValue(v)}`);
|
|
6790
|
+
}
|
|
6791
|
+
}
|
|
6792
|
+
}
|
|
6793
|
+
if (model.constraints) {
|
|
6794
|
+
for (const [cName, c] of Object.entries(model.constraints)) {
|
|
6795
|
+
lines.push("");
|
|
6796
|
+
lines.push(`[[models.${modelName}.unique_constraints]]`);
|
|
6797
|
+
lines.push(`name = ${tomlValue(cName)}`);
|
|
6798
|
+
lines.push(`fields = [${c.fields.map((f) => tomlValue(f)).join(", ")}]`);
|
|
6799
|
+
}
|
|
6800
|
+
}
|
|
6801
|
+
}
|
|
6802
|
+
lines.push("");
|
|
6803
|
+
return lines.join("\n");
|
|
6804
|
+
}
|
|
6805
|
+
|
|
6806
|
+
// src/models/tomlLoader.ts
|
|
6807
|
+
var import_smol_toml = require("smol-toml");
|
|
6808
|
+
var VALID_FIELD_TYPES = /* @__PURE__ */ new Set([
|
|
6809
|
+
"string",
|
|
6810
|
+
"number",
|
|
6811
|
+
"boolean",
|
|
6812
|
+
"date",
|
|
6813
|
+
"id",
|
|
6814
|
+
"stringset"
|
|
6815
|
+
]);
|
|
6816
|
+
function parseFieldOptions(raw) {
|
|
6817
|
+
if (!raw.type || !VALID_FIELD_TYPES.has(raw.type)) {
|
|
6818
|
+
throw new Error(
|
|
6819
|
+
`Invalid field type "${raw.type}". Must be one of: ${[...VALID_FIELD_TYPES].join(", ")}`
|
|
6820
|
+
);
|
|
6821
|
+
}
|
|
6822
|
+
const opts = { type: raw.type };
|
|
6823
|
+
if (raw.indexed === true) opts.indexed = true;
|
|
6824
|
+
if (raw.unique === true) opts.unique = true;
|
|
6825
|
+
if (raw.required === true) opts.required = true;
|
|
6826
|
+
if (raw.auto_assign === true) opts.autoAssign = true;
|
|
6827
|
+
if (raw.max_length !== void 0) opts.maxLength = raw.max_length;
|
|
6828
|
+
if (raw.max_count !== void 0) opts.maxCount = raw.max_count;
|
|
6829
|
+
if (raw.default !== void 0) opts.default = raw.default;
|
|
6830
|
+
return opts;
|
|
6831
|
+
}
|
|
6832
|
+
function requireField(raw, field, context) {
|
|
6833
|
+
if (!raw[field]) {
|
|
6834
|
+
throw new Error(`Relationship ${context}: missing required field "${field}"`);
|
|
6835
|
+
}
|
|
6836
|
+
}
|
|
6837
|
+
function parseRelationship(raw) {
|
|
6838
|
+
const type = raw.type;
|
|
6839
|
+
if (type === "refersTo") {
|
|
6840
|
+
requireField(raw, "model", "refersTo");
|
|
6841
|
+
requireField(raw, "related_id_field", "refersTo");
|
|
6842
|
+
return {
|
|
6843
|
+
type: "refersTo",
|
|
6844
|
+
model: raw.model,
|
|
6845
|
+
relatedIdField: raw.related_id_field
|
|
6846
|
+
};
|
|
6847
|
+
}
|
|
6848
|
+
if (type === "hasMany") {
|
|
6849
|
+
requireField(raw, "model", "hasMany");
|
|
6850
|
+
requireField(raw, "related_id_field", "hasMany");
|
|
6851
|
+
const rel = {
|
|
6852
|
+
type: "hasMany",
|
|
6853
|
+
model: raw.model,
|
|
6854
|
+
relatedIdField: raw.related_id_field
|
|
6855
|
+
};
|
|
6856
|
+
if (raw.order_by_field) rel.orderByField = raw.order_by_field;
|
|
6857
|
+
if (raw.order_direction) rel.orderDirection = raw.order_direction;
|
|
6858
|
+
return rel;
|
|
6859
|
+
}
|
|
6860
|
+
if (type === "hasManyThrough") {
|
|
6861
|
+
requireField(raw, "model", "hasManyThrough");
|
|
6862
|
+
requireField(raw, "join_model", "hasManyThrough");
|
|
6863
|
+
requireField(raw, "join_model_local_field", "hasManyThrough");
|
|
6864
|
+
requireField(raw, "join_model_related_field", "hasManyThrough");
|
|
6865
|
+
const rel = {
|
|
6866
|
+
type: "hasManyThrough",
|
|
6867
|
+
model: raw.model,
|
|
6868
|
+
joinModel: raw.join_model,
|
|
6869
|
+
joinModelLocalField: raw.join_model_local_field,
|
|
6870
|
+
joinModelRelatedField: raw.join_model_related_field
|
|
6871
|
+
};
|
|
6872
|
+
if (raw.join_model_order_by_field)
|
|
6873
|
+
rel.joinModelOrderByField = raw.join_model_order_by_field;
|
|
6874
|
+
if (raw.join_model_order_direction)
|
|
6875
|
+
rel.joinModelOrderDirection = raw.join_model_order_direction;
|
|
6876
|
+
return rel;
|
|
6877
|
+
}
|
|
6878
|
+
throw new Error(`Unknown relationship type: ${type}`);
|
|
6879
|
+
}
|
|
6880
|
+
function loadSchemaFromTomlString(tomlString) {
|
|
6881
|
+
const parsed = (0, import_smol_toml.parse)(tomlString);
|
|
6882
|
+
const models = parsed.models;
|
|
6883
|
+
if (!models || typeof models !== "object") {
|
|
6884
|
+
throw new Error("TOML schema must have a [models] section");
|
|
6885
|
+
}
|
|
6886
|
+
const schemas = [];
|
|
6887
|
+
for (const [modelName, modelDef] of Object.entries(models)) {
|
|
6888
|
+
const fields = {};
|
|
6889
|
+
if (modelDef.fields) {
|
|
6890
|
+
for (const [fieldName, fieldDef] of Object.entries(modelDef.fields)) {
|
|
6891
|
+
fields[fieldName] = parseFieldOptions(fieldDef);
|
|
6892
|
+
}
|
|
6893
|
+
}
|
|
6894
|
+
let relationships;
|
|
6895
|
+
if (modelDef.relationships) {
|
|
6896
|
+
relationships = {};
|
|
6897
|
+
for (const [relName, relDef] of Object.entries(
|
|
6898
|
+
modelDef.relationships
|
|
6899
|
+
)) {
|
|
6900
|
+
relationships[relName] = parseRelationship(relDef);
|
|
6901
|
+
}
|
|
6902
|
+
}
|
|
6903
|
+
let uniqueConstraints;
|
|
6904
|
+
if (modelDef.unique_constraints) {
|
|
6905
|
+
uniqueConstraints = [];
|
|
6906
|
+
for (const raw of modelDef.unique_constraints) {
|
|
6907
|
+
uniqueConstraints.push({
|
|
6908
|
+
name: raw.name,
|
|
6909
|
+
fields: [...raw.fields]
|
|
6910
|
+
});
|
|
6911
|
+
}
|
|
6912
|
+
}
|
|
6913
|
+
schemas.push(
|
|
6914
|
+
defineModelSchema({
|
|
6915
|
+
name: modelName,
|
|
6916
|
+
fields,
|
|
6917
|
+
options: {
|
|
6918
|
+
uniqueConstraints,
|
|
6919
|
+
relationships
|
|
6920
|
+
}
|
|
6921
|
+
})
|
|
6922
|
+
);
|
|
6923
|
+
}
|
|
6924
|
+
return schemas;
|
|
6925
|
+
}
|
|
6926
|
+
|
|
6927
|
+
// src/browser.ts
|
|
6928
|
+
init_metaSync();
|
package/dist/browser.d.cts
CHANGED
|
@@ -875,4 +875,129 @@ type HasManyThroughMethod<T> = (options?: PaginationOptions) => Promise<Paginate
|
|
|
875
875
|
type AddRelationMethod<T> = (target: T | string) => Promise<void>;
|
|
876
876
|
type RemoveRelationMethod<T> = (target: T | string) => Promise<void>;
|
|
877
877
|
|
|
878
|
-
|
|
878
|
+
/**
|
|
879
|
+
* YDoc Schema Discovery
|
|
880
|
+
*
|
|
881
|
+
* Reads _meta_* YMaps from a YDoc and returns a plain JSON description
|
|
882
|
+
* of the schema. Works with any YDoc — no BaseModel or database needed.
|
|
883
|
+
*
|
|
884
|
+
* Usage:
|
|
885
|
+
* import { discoverSchema } from "js-bao";
|
|
886
|
+
* const schema = discoverSchema(yDoc);
|
|
887
|
+
*/
|
|
888
|
+
|
|
889
|
+
interface DiscoveredField {
|
|
890
|
+
type: string;
|
|
891
|
+
indexed?: boolean;
|
|
892
|
+
unique?: boolean;
|
|
893
|
+
required?: boolean;
|
|
894
|
+
default?: string | number | boolean;
|
|
895
|
+
autoAssign?: boolean;
|
|
896
|
+
maxLength?: number;
|
|
897
|
+
maxCount?: number;
|
|
898
|
+
}
|
|
899
|
+
interface DiscoveredConstraint {
|
|
900
|
+
type: string;
|
|
901
|
+
fields: string[];
|
|
902
|
+
}
|
|
903
|
+
interface DiscoveredRelationship {
|
|
904
|
+
type: string;
|
|
905
|
+
model: string;
|
|
906
|
+
[key: string]: any;
|
|
907
|
+
}
|
|
908
|
+
interface DiscoveredModel {
|
|
909
|
+
fields: Record<string, DiscoveredField>;
|
|
910
|
+
constraints?: Record<string, DiscoveredConstraint>;
|
|
911
|
+
relationships?: Record<string, DiscoveredRelationship>;
|
|
912
|
+
}
|
|
913
|
+
interface DiscoveredSchema {
|
|
914
|
+
models: Record<string, DiscoveredModel>;
|
|
915
|
+
}
|
|
916
|
+
/**
|
|
917
|
+
* Discover the schema embedded in a YDoc by reading its `_meta_*` maps.
|
|
918
|
+
*
|
|
919
|
+
* Returns a plain JSON object describing every model that has metadata.
|
|
920
|
+
* Does not require BaseModel, a database, or any schema registration —
|
|
921
|
+
* just a Y.Doc.
|
|
922
|
+
*/
|
|
923
|
+
declare function discoverSchema(yDoc: Y.Doc): DiscoveredSchema;
|
|
924
|
+
/**
|
|
925
|
+
* List model names that have data in the YDoc (non-`_` prefixed top-level maps).
|
|
926
|
+
*/
|
|
927
|
+
declare function discoverModelNames(yDoc: Y.Doc): string[];
|
|
928
|
+
/**
|
|
929
|
+
* Convert a DiscoveredSchema to a TOML string matching the js-bao
|
|
930
|
+
* schema format.
|
|
931
|
+
*
|
|
932
|
+
* Usage:
|
|
933
|
+
* const schema = discoverSchema(yDoc);
|
|
934
|
+
* const toml = schemaToToml(schema);
|
|
935
|
+
*/
|
|
936
|
+
declare function schemaToToml(schema: DiscoveredSchema): string;
|
|
937
|
+
|
|
938
|
+
/**
|
|
939
|
+
* TOML Schema Loader
|
|
940
|
+
*
|
|
941
|
+
* Parses a TOML schema file and returns an array of DefinedModelSchema
|
|
942
|
+
* objects. Can be used in place of manual `defineModelSchema()` calls.
|
|
943
|
+
*
|
|
944
|
+
* TOML conventions:
|
|
945
|
+
* - Property names are snake_case (auto_assign, max_count, …)
|
|
946
|
+
* - Model names and field names are as-is (user-chosen)
|
|
947
|
+
* - Relationships live under [models.*.relationships.*]
|
|
948
|
+
* - Compound unique constraints are [[models.*.unique_constraints]]
|
|
949
|
+
*/
|
|
950
|
+
|
|
951
|
+
/**
|
|
952
|
+
* Parse a TOML string and return an array of DefinedModelSchema objects.
|
|
953
|
+
*/
|
|
954
|
+
declare function loadSchemaFromTomlString(tomlString: string): DefinedModelSchema[];
|
|
955
|
+
|
|
956
|
+
/**
|
|
957
|
+
* Meta Sync — writes _meta_* YMaps into a YDoc.
|
|
958
|
+
*
|
|
959
|
+
* Each model with data in a YDoc gets a `_meta_{modelName}` YMap that
|
|
960
|
+
* describes the model's fields, constraints, and relationships. This
|
|
961
|
+
* lets any language that can read a YDoc discover the schema without
|
|
962
|
+
* external configuration.
|
|
963
|
+
*
|
|
964
|
+
* Two modes:
|
|
965
|
+
* 1. **Schema-aware** — full schema known (from defineModelSchema / TOML).
|
|
966
|
+
* Writes field metadata, constraints, and relationships.
|
|
967
|
+
* 2. **Infer-on-write** — no schema. Infers types from record values.
|
|
968
|
+
*/
|
|
969
|
+
|
|
970
|
+
/**
|
|
971
|
+
* Infer a _meta_ type string from a JS runtime value.
|
|
972
|
+
*/
|
|
973
|
+
declare function inferFieldType(value: unknown): "string" | "number" | "boolean" | "stringset" | null;
|
|
974
|
+
/**
|
|
975
|
+
* Register a named function default so metaSync can encode it.
|
|
976
|
+
* Called once per known default generator.
|
|
977
|
+
*/
|
|
978
|
+
declare function registerFunctionDefault(fn: Function, name: string): void;
|
|
979
|
+
/**
|
|
980
|
+
* Clear the sync cache for a specific doc (or all docs).
|
|
981
|
+
* Useful for testing or when schema changes at runtime.
|
|
982
|
+
*/
|
|
983
|
+
declare function clearMetaSyncCache(yDoc?: Y.Doc): void;
|
|
984
|
+
/**
|
|
985
|
+
* Sync full schema metadata into `_meta_{modelName}` inside a YDoc.
|
|
986
|
+
*
|
|
987
|
+
* Call this inside an existing `yDoc.transact()`. Y.Map `.set()` on
|
|
988
|
+
* identical values is a CRDT no-op so there is no overhead after the
|
|
989
|
+
* first write.
|
|
990
|
+
*
|
|
991
|
+
* Skips the sync if this (yDoc, modelName) pair has already been synced
|
|
992
|
+
* in the current session.
|
|
993
|
+
*/
|
|
994
|
+
declare function syncModelMeta(yDoc: Y.Doc, modelName: string, schema: ModelSchemaRuntimeShape): void;
|
|
995
|
+
/**
|
|
996
|
+
* Infer-on-write: when no schema is available, infer field types from
|
|
997
|
+
* the record data and write minimal _meta_.
|
|
998
|
+
*
|
|
999
|
+
* Call inside an existing `yDoc.transact()`.
|
|
1000
|
+
*/
|
|
1001
|
+
declare function syncInferredMeta(yDoc: Y.Doc, modelName: string, recordData: Record<string, any>): void;
|
|
1002
|
+
|
|
1003
|
+
export { type AddRelationMethod, type AggregationAliasDebugInfo, type AggregationOperation, type AggregationOptions, type AggregationResult, BaseModel, type DatabaseConfig, DatabaseEngine, type DatabaseEngineType, BrowserDatabaseFactory as DatabaseFactory, type DiscoveredConstraint, type DiscoveredField, type DiscoveredModel, type DiscoveredRelationship, type DiscoveredSchema, Field, type FieldOptions, type FieldType, type GroupByField, type HasManyMethod, type HasManyThroughMethod, type InferAttrs, type InitJsBaoOptions, type InitJsBaoResult, LogLevel, Logger, Model, type ModelConstructor, type ModelOptions, ModelRegistry, type PaginatedResult, type PaginationOptions, RecordNotFoundError, type RefersToMethod, type RegisteredModelInfo, type RemoveRelationMethod, type SQLJSEngineOptions, type Schema, SqljsEngine, type SqljsEngineOptions, StringSet, type StringSetMembership, type UniqueConstraintConfig, UniqueConstraintViolationError, attachAndRegisterModel, attachSchemaToClass, autoRegisterModel, clearMetaSyncCache, createModelClass, defineModelSchema, detectEnvironment, discoverModelNames, discoverSchema, features, generateULID, inferFieldType, initJsBao, isBrowser, isNode, loadSchemaFromTomlString, registerFunctionDefault, resetJsBao, schemaToToml, syncInferredMeta, syncModelMeta };
|
package/dist/browser.d.ts
CHANGED
|
@@ -875,4 +875,129 @@ type HasManyThroughMethod<T> = (options?: PaginationOptions) => Promise<Paginate
|
|
|
875
875
|
type AddRelationMethod<T> = (target: T | string) => Promise<void>;
|
|
876
876
|
type RemoveRelationMethod<T> = (target: T | string) => Promise<void>;
|
|
877
877
|
|
|
878
|
-
|
|
878
|
+
/**
|
|
879
|
+
* YDoc Schema Discovery
|
|
880
|
+
*
|
|
881
|
+
* Reads _meta_* YMaps from a YDoc and returns a plain JSON description
|
|
882
|
+
* of the schema. Works with any YDoc — no BaseModel or database needed.
|
|
883
|
+
*
|
|
884
|
+
* Usage:
|
|
885
|
+
* import { discoverSchema } from "js-bao";
|
|
886
|
+
* const schema = discoverSchema(yDoc);
|
|
887
|
+
*/
|
|
888
|
+
|
|
889
|
+
interface DiscoveredField {
|
|
890
|
+
type: string;
|
|
891
|
+
indexed?: boolean;
|
|
892
|
+
unique?: boolean;
|
|
893
|
+
required?: boolean;
|
|
894
|
+
default?: string | number | boolean;
|
|
895
|
+
autoAssign?: boolean;
|
|
896
|
+
maxLength?: number;
|
|
897
|
+
maxCount?: number;
|
|
898
|
+
}
|
|
899
|
+
interface DiscoveredConstraint {
|
|
900
|
+
type: string;
|
|
901
|
+
fields: string[];
|
|
902
|
+
}
|
|
903
|
+
interface DiscoveredRelationship {
|
|
904
|
+
type: string;
|
|
905
|
+
model: string;
|
|
906
|
+
[key: string]: any;
|
|
907
|
+
}
|
|
908
|
+
interface DiscoveredModel {
|
|
909
|
+
fields: Record<string, DiscoveredField>;
|
|
910
|
+
constraints?: Record<string, DiscoveredConstraint>;
|
|
911
|
+
relationships?: Record<string, DiscoveredRelationship>;
|
|
912
|
+
}
|
|
913
|
+
interface DiscoveredSchema {
|
|
914
|
+
models: Record<string, DiscoveredModel>;
|
|
915
|
+
}
|
|
916
|
+
/**
|
|
917
|
+
* Discover the schema embedded in a YDoc by reading its `_meta_*` maps.
|
|
918
|
+
*
|
|
919
|
+
* Returns a plain JSON object describing every model that has metadata.
|
|
920
|
+
* Does not require BaseModel, a database, or any schema registration —
|
|
921
|
+
* just a Y.Doc.
|
|
922
|
+
*/
|
|
923
|
+
declare function discoverSchema(yDoc: Y.Doc): DiscoveredSchema;
|
|
924
|
+
/**
|
|
925
|
+
* List model names that have data in the YDoc (non-`_` prefixed top-level maps).
|
|
926
|
+
*/
|
|
927
|
+
declare function discoverModelNames(yDoc: Y.Doc): string[];
|
|
928
|
+
/**
|
|
929
|
+
* Convert a DiscoveredSchema to a TOML string matching the js-bao
|
|
930
|
+
* schema format.
|
|
931
|
+
*
|
|
932
|
+
* Usage:
|
|
933
|
+
* const schema = discoverSchema(yDoc);
|
|
934
|
+
* const toml = schemaToToml(schema);
|
|
935
|
+
*/
|
|
936
|
+
declare function schemaToToml(schema: DiscoveredSchema): string;
|
|
937
|
+
|
|
938
|
+
/**
|
|
939
|
+
* TOML Schema Loader
|
|
940
|
+
*
|
|
941
|
+
* Parses a TOML schema file and returns an array of DefinedModelSchema
|
|
942
|
+
* objects. Can be used in place of manual `defineModelSchema()` calls.
|
|
943
|
+
*
|
|
944
|
+
* TOML conventions:
|
|
945
|
+
* - Property names are snake_case (auto_assign, max_count, …)
|
|
946
|
+
* - Model names and field names are as-is (user-chosen)
|
|
947
|
+
* - Relationships live under [models.*.relationships.*]
|
|
948
|
+
* - Compound unique constraints are [[models.*.unique_constraints]]
|
|
949
|
+
*/
|
|
950
|
+
|
|
951
|
+
/**
|
|
952
|
+
* Parse a TOML string and return an array of DefinedModelSchema objects.
|
|
953
|
+
*/
|
|
954
|
+
declare function loadSchemaFromTomlString(tomlString: string): DefinedModelSchema[];
|
|
955
|
+
|
|
956
|
+
/**
|
|
957
|
+
* Meta Sync — writes _meta_* YMaps into a YDoc.
|
|
958
|
+
*
|
|
959
|
+
* Each model with data in a YDoc gets a `_meta_{modelName}` YMap that
|
|
960
|
+
* describes the model's fields, constraints, and relationships. This
|
|
961
|
+
* lets any language that can read a YDoc discover the schema without
|
|
962
|
+
* external configuration.
|
|
963
|
+
*
|
|
964
|
+
* Two modes:
|
|
965
|
+
* 1. **Schema-aware** — full schema known (from defineModelSchema / TOML).
|
|
966
|
+
* Writes field metadata, constraints, and relationships.
|
|
967
|
+
* 2. **Infer-on-write** — no schema. Infers types from record values.
|
|
968
|
+
*/
|
|
969
|
+
|
|
970
|
+
/**
|
|
971
|
+
* Infer a _meta_ type string from a JS runtime value.
|
|
972
|
+
*/
|
|
973
|
+
declare function inferFieldType(value: unknown): "string" | "number" | "boolean" | "stringset" | null;
|
|
974
|
+
/**
|
|
975
|
+
* Register a named function default so metaSync can encode it.
|
|
976
|
+
* Called once per known default generator.
|
|
977
|
+
*/
|
|
978
|
+
declare function registerFunctionDefault(fn: Function, name: string): void;
|
|
979
|
+
/**
|
|
980
|
+
* Clear the sync cache for a specific doc (or all docs).
|
|
981
|
+
* Useful for testing or when schema changes at runtime.
|
|
982
|
+
*/
|
|
983
|
+
declare function clearMetaSyncCache(yDoc?: Y.Doc): void;
|
|
984
|
+
/**
|
|
985
|
+
* Sync full schema metadata into `_meta_{modelName}` inside a YDoc.
|
|
986
|
+
*
|
|
987
|
+
* Call this inside an existing `yDoc.transact()`. Y.Map `.set()` on
|
|
988
|
+
* identical values is a CRDT no-op so there is no overhead after the
|
|
989
|
+
* first write.
|
|
990
|
+
*
|
|
991
|
+
* Skips the sync if this (yDoc, modelName) pair has already been synced
|
|
992
|
+
* in the current session.
|
|
993
|
+
*/
|
|
994
|
+
declare function syncModelMeta(yDoc: Y.Doc, modelName: string, schema: ModelSchemaRuntimeShape): void;
|
|
995
|
+
/**
|
|
996
|
+
* Infer-on-write: when no schema is available, infer field types from
|
|
997
|
+
* the record data and write minimal _meta_.
|
|
998
|
+
*
|
|
999
|
+
* Call inside an existing `yDoc.transact()`.
|
|
1000
|
+
*/
|
|
1001
|
+
declare function syncInferredMeta(yDoc: Y.Doc, modelName: string, recordData: Record<string, any>): void;
|
|
1002
|
+
|
|
1003
|
+
export { type AddRelationMethod, type AggregationAliasDebugInfo, type AggregationOperation, type AggregationOptions, type AggregationResult, BaseModel, type DatabaseConfig, DatabaseEngine, type DatabaseEngineType, BrowserDatabaseFactory as DatabaseFactory, type DiscoveredConstraint, type DiscoveredField, type DiscoveredModel, type DiscoveredRelationship, type DiscoveredSchema, Field, type FieldOptions, type FieldType, type GroupByField, type HasManyMethod, type HasManyThroughMethod, type InferAttrs, type InitJsBaoOptions, type InitJsBaoResult, LogLevel, Logger, Model, type ModelConstructor, type ModelOptions, ModelRegistry, type PaginatedResult, type PaginationOptions, RecordNotFoundError, type RefersToMethod, type RegisteredModelInfo, type RemoveRelationMethod, type SQLJSEngineOptions, type Schema, SqljsEngine, type SqljsEngineOptions, StringSet, type StringSetMembership, type UniqueConstraintConfig, UniqueConstraintViolationError, attachAndRegisterModel, attachSchemaToClass, autoRegisterModel, clearMetaSyncCache, createModelClass, defineModelSchema, detectEnvironment, discoverModelNames, discoverSchema, features, generateULID, inferFieldType, initJsBao, isBrowser, isNode, loadSchemaFromTomlString, registerFunctionDefault, resetJsBao, schemaToToml, syncInferredMeta, syncModelMeta };
|