@almadar/runtime 6.8.0 → 6.9.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.
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { InMemoryPersistence, OrbitalServerRuntime, collectDeclaredConfigDefaults, createOrbitalServerRuntime } from './chunk-
|
|
1
|
+
export { InMemoryPersistence, OrbitalServerRuntime, collectDeclaredConfigDefaults, createOrbitalServerRuntime } from './chunk-TNK77RLG.js';
|
|
2
2
|
import './chunk-PZ5AY32C.js';
|
|
3
3
|
//# sourceMappingURL=OrbitalServerRuntime.js.map
|
|
4
4
|
//# sourceMappingURL=OrbitalServerRuntime.js.map
|
|
@@ -1703,7 +1703,7 @@ function picsumUrl(entityName, fieldName, width = 400, height = 400) {
|
|
|
1703
1703
|
return `https://picsum.photos/seed/${encodeURIComponent(seed)}/${width}/${height}`;
|
|
1704
1704
|
}
|
|
1705
1705
|
var SEED_REFERENCE_TIMESTAMP = "2024-01-01T00:00:00.000Z";
|
|
1706
|
-
var MockPersistenceAdapter = class {
|
|
1706
|
+
var MockPersistenceAdapter = class _MockPersistenceAdapter {
|
|
1707
1707
|
stores = /* @__PURE__ */ new Map();
|
|
1708
1708
|
schemas = /* @__PURE__ */ new Map();
|
|
1709
1709
|
idCounters = /* @__PURE__ */ new Map();
|
|
@@ -1764,6 +1764,51 @@ var MockPersistenceAdapter = class {
|
|
|
1764
1764
|
const count = seedCount ?? this.config.defaultSeedCount ?? 6;
|
|
1765
1765
|
this.seed(schema.name, schema.fields, count);
|
|
1766
1766
|
}
|
|
1767
|
+
this.linkRelationFields();
|
|
1768
|
+
}
|
|
1769
|
+
/**
|
|
1770
|
+
* Walk every row of every registered entity and fill in `type: "relation"`
|
|
1771
|
+
* fields with real IDs from the target entity's store. Without this pass,
|
|
1772
|
+
* relation fields stay as placeholder `[]` / `""` and `populateRelations`
|
|
1773
|
+
* in OrbitalServerRuntime has nothing to hydrate — catalog/preview demos
|
|
1774
|
+
* of nested-tree atoms (e.g. std-thread-comments-linear with ThreadPost.
|
|
1775
|
+
* replies → [ThreadPost]) render empty reply cards.
|
|
1776
|
+
*
|
|
1777
|
+
* For self-referential relations, each row gets 2–4 sibling IDs (excluding
|
|
1778
|
+
* self). For cross-entity relations, IDs are picked from the target store.
|
|
1779
|
+
* The runtime caps recursion at depth=2 in `populateRelations`, so
|
|
1780
|
+
* grandparent-of-self cycles render two levels deep then stop.
|
|
1781
|
+
*/
|
|
1782
|
+
linkRelationFields() {
|
|
1783
|
+
for (const [normalizedName, schema] of this.schemas) {
|
|
1784
|
+
const store = this.stores.get(normalizedName);
|
|
1785
|
+
if (!store) continue;
|
|
1786
|
+
const relationFields = schema.fields.filter(
|
|
1787
|
+
(f) => f.type === "relation"
|
|
1788
|
+
);
|
|
1789
|
+
if (relationFields.length === 0) continue;
|
|
1790
|
+
for (const row of store.values()) {
|
|
1791
|
+
for (const field of relationFields) {
|
|
1792
|
+
const targetStore = this.stores.get(field.relation.entity.toLowerCase());
|
|
1793
|
+
if (!targetStore || targetStore.size === 0) continue;
|
|
1794
|
+
const selfId = row["id"];
|
|
1795
|
+
const sameStore = targetStore === store;
|
|
1796
|
+
const eligible = [];
|
|
1797
|
+
for (const id of targetStore.keys()) {
|
|
1798
|
+
if (sameStore && id === selfId) continue;
|
|
1799
|
+
eligible.push(id);
|
|
1800
|
+
}
|
|
1801
|
+
if (eligible.length === 0) continue;
|
|
1802
|
+
const cardinality = field.relation.cardinality ?? "many";
|
|
1803
|
+
if (cardinality === "one" || cardinality === "many-to-one") {
|
|
1804
|
+
row[field.name] = faker.helpers.arrayElement(eligible);
|
|
1805
|
+
} else {
|
|
1806
|
+
const pickCount = Math.min(eligible.length, faker.number.int({ min: 2, max: 4 }));
|
|
1807
|
+
row[field.name] = faker.helpers.shuffle(eligible.slice()).slice(0, pickCount);
|
|
1808
|
+
}
|
|
1809
|
+
}
|
|
1810
|
+
}
|
|
1811
|
+
}
|
|
1767
1812
|
}
|
|
1768
1813
|
/**
|
|
1769
1814
|
* Seed an entity with pre-authored instance data.
|
|
@@ -1815,6 +1860,7 @@ var MockPersistenceAdapter = class {
|
|
|
1815
1860
|
updatedAt: SEED_REFERENCE_TIMESTAMP
|
|
1816
1861
|
};
|
|
1817
1862
|
for (const field of fields) {
|
|
1863
|
+
if (!field.name) continue;
|
|
1818
1864
|
if (field.name === "id" || field.name === "createdAt" || field.name === "updatedAt") {
|
|
1819
1865
|
continue;
|
|
1820
1866
|
}
|
|
@@ -1822,18 +1868,26 @@ var MockPersistenceAdapter = class {
|
|
|
1822
1868
|
}
|
|
1823
1869
|
return item;
|
|
1824
1870
|
}
|
|
1871
|
+
/** Max nesting depth for recursive array/object schemas (e.g. a Comment
|
|
1872
|
+
* entity whose `replies: [Comment]` field references itself). Without
|
|
1873
|
+
* this guard, generateArrayValue → generateObjectValue → generateArray…
|
|
1874
|
+
* recurses until stack overflow on every recursive type. Three levels
|
|
1875
|
+
* is enough to render a useful thread depth (parent → reply → sub-reply)
|
|
1876
|
+
* in catalog/preview without blowing the fixture. */
|
|
1877
|
+
static MAX_NESTED_DEPTH = 3;
|
|
1825
1878
|
/**
|
|
1826
1879
|
* Generate a mock value for a field based on its schema.
|
|
1827
1880
|
*/
|
|
1828
|
-
generateFieldValue(entityName, field, index) {
|
|
1881
|
+
generateFieldValue(entityName, field, index, depth = 0) {
|
|
1829
1882
|
const fieldTypeLc = field.type.toLowerCase();
|
|
1883
|
+
const values = "values" in field ? field.values : void 0;
|
|
1830
1884
|
mockLog.debug("field:generate", {
|
|
1831
1885
|
entityName,
|
|
1832
1886
|
fieldName: field.name,
|
|
1833
1887
|
fieldType: fieldTypeLc,
|
|
1834
|
-
hasValues: !!
|
|
1835
|
-
valuesCount:
|
|
1836
|
-
values:
|
|
1888
|
+
hasValues: !!values?.length,
|
|
1889
|
+
valuesCount: values?.length ?? 0,
|
|
1890
|
+
values: values?.length ? values.join(",") : null,
|
|
1837
1891
|
format: field.format ?? null,
|
|
1838
1892
|
hasDefault: field.default !== void 0
|
|
1839
1893
|
});
|
|
@@ -1841,7 +1895,7 @@ var MockPersistenceAdapter = class {
|
|
|
1841
1895
|
if (isNumeric && field.default !== void 0) {
|
|
1842
1896
|
return field.default;
|
|
1843
1897
|
}
|
|
1844
|
-
switch (
|
|
1898
|
+
switch (field.type) {
|
|
1845
1899
|
case "string":
|
|
1846
1900
|
return this.generateStringValue(entityName, field, index);
|
|
1847
1901
|
case "number":
|
|
@@ -1858,12 +1912,11 @@ var MockPersistenceAdapter = class {
|
|
|
1858
1912
|
}
|
|
1859
1913
|
return null;
|
|
1860
1914
|
case "relation":
|
|
1861
|
-
return
|
|
1862
|
-
// Relations need special handling
|
|
1915
|
+
return field.relation?.cardinality === "one" ? "" : [];
|
|
1863
1916
|
case "array":
|
|
1864
|
-
return this.generateArrayValue(entityName, field, index);
|
|
1917
|
+
return this.generateArrayValue(entityName, field, index, depth);
|
|
1865
1918
|
case "object":
|
|
1866
|
-
return this.generateObjectValue(entityName, field, index);
|
|
1919
|
+
return this.generateObjectValue(entityName, field, index, depth);
|
|
1867
1920
|
default:
|
|
1868
1921
|
return this.generateStringValue(entityName, field, index);
|
|
1869
1922
|
}
|
|
@@ -1877,16 +1930,18 @@ var MockPersistenceAdapter = class {
|
|
|
1877
1930
|
* with no element schema), falls back to an empty array — the historical
|
|
1878
1931
|
* behavior.
|
|
1879
1932
|
*/
|
|
1880
|
-
generateArrayValue(entityName, field, index) {
|
|
1881
|
-
if (!field.items) return [];
|
|
1933
|
+
generateArrayValue(entityName, field, index, depth = 0) {
|
|
1934
|
+
if (field.type !== "array" || !field.items) return [];
|
|
1935
|
+
if (depth >= _MockPersistenceAdapter.MAX_NESTED_DEPTH) return [];
|
|
1882
1936
|
const count = faker.number.int({ min: 3, max: 5 });
|
|
1883
1937
|
const out = [];
|
|
1938
|
+
const elementName = field.name ?? "item";
|
|
1884
1939
|
for (let i = 0; i < count; i++) {
|
|
1885
1940
|
const elementField = {
|
|
1886
1941
|
...field.items,
|
|
1887
|
-
name: `${
|
|
1942
|
+
name: `${elementName}[${i}]`
|
|
1888
1943
|
};
|
|
1889
|
-
out.push(this.generateFieldValue(entityName, elementField, index * 10 + i));
|
|
1944
|
+
out.push(this.generateFieldValue(entityName, elementField, index * 10 + i, depth + 1));
|
|
1890
1945
|
}
|
|
1891
1946
|
return out;
|
|
1892
1947
|
}
|
|
@@ -1896,12 +1951,13 @@ var MockPersistenceAdapter = class {
|
|
|
1896
1951
|
* `generateFieldValue` per property so nested objects-of-arrays-of-objects
|
|
1897
1952
|
* compose correctly.
|
|
1898
1953
|
*/
|
|
1899
|
-
generateObjectValue(entityName, field, index) {
|
|
1954
|
+
generateObjectValue(entityName, field, index, depth = 0) {
|
|
1900
1955
|
if (!field.properties) return null;
|
|
1956
|
+
if (depth >= _MockPersistenceAdapter.MAX_NESTED_DEPTH) return null;
|
|
1901
1957
|
const out = {};
|
|
1902
1958
|
for (const [propName, propField] of Object.entries(field.properties)) {
|
|
1903
1959
|
const childField = { ...propField, name: propName };
|
|
1904
|
-
out[propName] = this.generateFieldValue(entityName, childField, index);
|
|
1960
|
+
out[propName] = this.generateFieldValue(entityName, childField, index, depth + 1);
|
|
1905
1961
|
}
|
|
1906
1962
|
return out;
|
|
1907
1963
|
}
|
|
@@ -1913,9 +1969,11 @@ var MockPersistenceAdapter = class {
|
|
|
1913
1969
|
* declare `format: "email"`; if they need an enum, they declare `values: [...]`.
|
|
1914
1970
|
*/
|
|
1915
1971
|
generateStringValue(entityName, field, _index) {
|
|
1916
|
-
|
|
1917
|
-
|
|
1972
|
+
const values = "values" in field ? field.values : void 0;
|
|
1973
|
+
if (values && values.length > 0) {
|
|
1974
|
+
return faker.helpers.arrayElement(values);
|
|
1918
1975
|
}
|
|
1976
|
+
const fieldName = field.name ?? "field";
|
|
1919
1977
|
switch (field.format) {
|
|
1920
1978
|
case "email":
|
|
1921
1979
|
return faker.internet.email();
|
|
@@ -1932,11 +1990,11 @@ var MockPersistenceAdapter = class {
|
|
|
1932
1990
|
case "image":
|
|
1933
1991
|
case "avatar":
|
|
1934
1992
|
case "thumbnail":
|
|
1935
|
-
return picsumUrl(entityName,
|
|
1993
|
+
return picsumUrl(entityName, fieldName);
|
|
1936
1994
|
}
|
|
1937
|
-
const lname =
|
|
1995
|
+
const lname = fieldName.toLowerCase();
|
|
1938
1996
|
if (lname === "image" || lname === "imageurl" || lname === "image_url" || lname === "photo" || lname === "photourl" || lname === "photo_url" || lname === "avatar" || lname === "avatarurl" || lname === "avatar_url" || lname === "thumbnail" || lname === "thumbnailurl" || lname === "thumbnail_url" || lname === "picture" || lname === "pictureurl" || lname === "cover" || lname === "coverurl" || lname === "banner" || lname === "bannerurl") {
|
|
1939
|
-
return picsumUrl(entityName,
|
|
1997
|
+
return picsumUrl(entityName, fieldName);
|
|
1940
1998
|
}
|
|
1941
1999
|
const value = faker.lorem.words(2);
|
|
1942
2000
|
mockLog.debug("field:fallback-lorem", () => ({
|
|
@@ -3626,32 +3684,6 @@ function needsPreprocessing(schema) {
|
|
|
3626
3684
|
}
|
|
3627
3685
|
return false;
|
|
3628
3686
|
}
|
|
3629
|
-
function mapFieldForMock(f) {
|
|
3630
|
-
const rec = f;
|
|
3631
|
-
const out = {
|
|
3632
|
-
name: f.name,
|
|
3633
|
-
type: rec["type"]
|
|
3634
|
-
};
|
|
3635
|
-
if (typeof rec["required"] === "boolean") out.required = rec["required"];
|
|
3636
|
-
if (Array.isArray(rec["values"])) out.values = rec["values"];
|
|
3637
|
-
if (rec["default"] !== void 0) out.default = rec["default"];
|
|
3638
|
-
if (typeof rec["format"] === "string") out.format = rec["format"];
|
|
3639
|
-
const items = rec["items"];
|
|
3640
|
-
if (items && typeof items === "object" && "type" in items) {
|
|
3641
|
-
out.items = mapFieldForMock({ name: "", ...items });
|
|
3642
|
-
}
|
|
3643
|
-
const properties = rec["properties"];
|
|
3644
|
-
if (properties && typeof properties === "object" && !Array.isArray(properties)) {
|
|
3645
|
-
const propsOut = {};
|
|
3646
|
-
for (const [k, v] of Object.entries(properties)) {
|
|
3647
|
-
if (v && typeof v === "object" && "type" in v) {
|
|
3648
|
-
propsOut[k] = mapFieldForMock({ name: k, ...v });
|
|
3649
|
-
}
|
|
3650
|
-
}
|
|
3651
|
-
if (Object.keys(propsOut).length > 0) out.properties = propsOut;
|
|
3652
|
-
}
|
|
3653
|
-
return out;
|
|
3654
|
-
}
|
|
3655
3687
|
var OrbitalServerRuntime = class {
|
|
3656
3688
|
orbitals = /* @__PURE__ */ new Map();
|
|
3657
3689
|
eventBus;
|
|
@@ -4068,7 +4100,7 @@ var OrbitalServerRuntime = class {
|
|
|
4068
4100
|
if (entity?.name && entity.fields) {
|
|
4069
4101
|
const fields = entity.fields.filter(
|
|
4070
4102
|
(f) => typeof f.name === "string" && f.name.length > 0
|
|
4071
|
-
)
|
|
4103
|
+
);
|
|
4072
4104
|
this.persistence.registerEntity({ name: entity.name, fields });
|
|
4073
4105
|
if (this.config.debug) {
|
|
4074
4106
|
persistLog.debug("mock:seeded", { entity: entity.name, count: this.persistence.count(entity.name) });
|
|
@@ -4083,7 +4115,7 @@ var OrbitalServerRuntime = class {
|
|
|
4083
4115
|
if (!auxEntity.name || !auxEntity.fields) continue;
|
|
4084
4116
|
const auxFields = auxEntity.fields.filter(
|
|
4085
4117
|
(f) => typeof f.name === "string" && f.name.length > 0
|
|
4086
|
-
)
|
|
4118
|
+
);
|
|
4087
4119
|
this.persistence.registerEntity({ name: auxEntity.name, fields: auxFields });
|
|
4088
4120
|
if (this.config.debug) {
|
|
4089
4121
|
persistLog.debug("mock:seeded-auxiliary", {
|
|
@@ -4365,7 +4397,7 @@ var OrbitalServerRuntime = class {
|
|
|
4365
4397
|
if (entity?.name && entity.fields) {
|
|
4366
4398
|
const fields = entity.fields.filter(
|
|
4367
4399
|
(f) => typeof f.name === "string" && f.name.length > 0
|
|
4368
|
-
)
|
|
4400
|
+
);
|
|
4369
4401
|
this.persistence.registerEntity({ name: entity.name, fields });
|
|
4370
4402
|
}
|
|
4371
4403
|
}
|
|
@@ -5443,5 +5475,5 @@ function buildMatcher(src, listenerOrbital) {
|
|
|
5443
5475
|
}
|
|
5444
5476
|
|
|
5445
5477
|
export { EffectExecutor, EventBus, HANDLER_MANIFEST, InMemoryPersistence, MockPersistenceAdapter, OrbitalServerRuntime, StateMachineManager, buildEmitsFromTraits, collectDeclaredConfigDefaults, containsBindings, createContextFromBindings, createInitialTraitState, createMockPersistence, createOrbitalServerRuntime, createTestExecutor, createUnifiedLoader, extractBindings, findInitialState, findTransition, formatPayloadValidationError, getIsolatedCollectionName, getNamespacedEvent, interpolateProps, interpolateValue, isBrowser, isElectron, isNamespacedEvent, isNode, normalizeEventKey, parseNamespacedEvent, preprocessSchema, processEvent, validateEventPayload, validatePayloadShapes };
|
|
5446
|
-
//# sourceMappingURL=chunk-
|
|
5447
|
-
//# sourceMappingURL=chunk-
|
|
5478
|
+
//# sourceMappingURL=chunk-TNK77RLG.js.map
|
|
5479
|
+
//# sourceMappingURL=chunk-TNK77RLG.js.map
|