@almadar/std 3.14.1 → 5.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/behaviors/exports/validation-report.json +2 -2
- package/dist/behaviors/exports/validation-report.json +2 -2
- package/dist/behaviors/exports-reader.js +71 -122
- package/dist/behaviors/exports-reader.js.map +1 -1
- package/dist/behaviors/functions/index.d.ts +10 -4
- package/dist/behaviors/functions/index.js +71 -122
- package/dist/behaviors/functions/index.js.map +1 -1
- package/dist/behaviors/index.js +71 -122
- package/dist/behaviors/index.js.map +1 -1
- package/dist/behaviors/query.js +71 -122
- package/dist/behaviors/query.js.map +1 -1
- package/dist/exports/validation-report.json +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +176 -125
- package/dist/index.js.map +1 -1
- package/dist/modules/agent.d.ts +1 -1
- package/dist/modules/array.d.ts +1 -1
- package/dist/modules/async.d.ts +1 -1
- package/dist/modules/composition.d.ts +27 -0
- package/dist/modules/composition.js +98 -0
- package/dist/modules/composition.js.map +1 -0
- package/dist/modules/contract.d.ts +1 -1
- package/dist/modules/data.d.ts +1 -1
- package/dist/modules/format.d.ts +1 -1
- package/dist/modules/graph.d.ts +1 -1
- package/dist/modules/index.d.ts +2 -1
- package/dist/modules/index.js +96 -1
- package/dist/modules/index.js.map +1 -1
- package/dist/modules/math.d.ts +1 -1
- package/dist/modules/nn.d.ts +1 -1
- package/dist/modules/object.d.ts +1 -1
- package/dist/modules/os.d.ts +1 -1
- package/dist/modules/prob.d.ts +1 -1
- package/dist/modules/str.d.ts +1 -1
- package/dist/modules/tensor.d.ts +1 -1
- package/dist/modules/time.d.ts +1 -1
- package/dist/modules/train.d.ts +1 -1
- package/dist/modules/validate.d.ts +1 -1
- package/dist/registry.d.ts +1 -1
- package/dist/registry.js +98 -3
- package/dist/registry.js.map +1 -1
- package/dist/{types-BjP5nVQd.d.ts → types-BGtQuBge.d.ts} +5 -3
- package/package.json +1 -1
|
@@ -1715,10 +1715,16 @@ declare function stdGameCanvas3d(params: StdGameCanvas3dParams): OrbitalDefiniti
|
|
|
1715
1715
|
* CRUD list molecule. Composes atoms via shared event bus:
|
|
1716
1716
|
* - stdBrowse: data-grid with item actions (fires CREATE, VIEW, EDIT, DELETE)
|
|
1717
1717
|
* - stdModal (x3): create form, edit form, detail view (responds to matching events)
|
|
1718
|
-
* - stdConfirmation: delete confirmation (responds to DELETE)
|
|
1719
|
-
*
|
|
1720
|
-
*
|
|
1721
|
-
*
|
|
1718
|
+
* - stdConfirmation: delete confirmation (responds to DELETE → CONFIRM_DELETE)
|
|
1719
|
+
*
|
|
1720
|
+
* Phase F.10: previously the delete confirmation was inlined into the browse
|
|
1721
|
+
* trait via post-processing (added a `deleting` state, three new transitions,
|
|
1722
|
+
* and patched the events array). That made std-list un-liftable AND prevented
|
|
1723
|
+
* any organism from composing it as a clean molecule. The refactored version
|
|
1724
|
+
* has 5 separate traits, all from extractTrait, no post-processing — so the
|
|
1725
|
+
* converter lifts every trait into a reference and the molecule itself
|
|
1726
|
+
* becomes a first-class composable unit that organisms can extend with the
|
|
1727
|
+
* same override surface molecules use over atoms.
|
|
1722
1728
|
*
|
|
1723
1729
|
* @level molecule
|
|
1724
1730
|
* @family crud
|
|
@@ -166,19 +166,14 @@ function buildTrait(c) {
|
|
|
166
166
|
const actionEvents = /* @__PURE__ */ new Set();
|
|
167
167
|
for (const a of c.headerActions) actionEvents.add(a.event);
|
|
168
168
|
for (const a of c.itemActions) actionEvents.add(a.event);
|
|
169
|
-
for (const re of c.refreshEvents) actionEvents.add(re);
|
|
170
169
|
const events = [
|
|
171
170
|
{ key: "INIT", name: "Initialize" },
|
|
172
171
|
...Array.from(actionEvents).map((e) => {
|
|
173
172
|
const needsId = c.itemActions.some((a) => a.event === e);
|
|
174
|
-
const isRefresh = c.refreshEvents.includes(e);
|
|
175
|
-
if (isRefresh) {
|
|
176
|
-
return { key: e, name: e, payload: [{ name: "data", type: "object", required: true }] };
|
|
177
|
-
}
|
|
178
173
|
return needsId ? { key: e, name: e, payload: [{ name: "id", type: "string", required: true }, { name: "row", type: "object" }] } : { key: e, name: e };
|
|
179
174
|
})
|
|
180
175
|
];
|
|
181
|
-
const listensDecl = c.refreshEvents.length > 0 ? c.refreshEvents.map((evt) => ({ event: evt, triggers:
|
|
176
|
+
const listensDecl = c.refreshEvents.length > 0 ? c.refreshEvents.map((evt) => ({ event: evt, triggers: "INIT" })) : void 0;
|
|
182
177
|
return {
|
|
183
178
|
name: c.traitName,
|
|
184
179
|
linkedEntity: entityName,
|
|
@@ -215,14 +210,7 @@ function buildTrait(c) {
|
|
|
215
210
|
]
|
|
216
211
|
}]
|
|
217
212
|
]
|
|
218
|
-
}
|
|
219
|
-
// Refresh self-loops: when modal atoms fire SAVE etc., re-fetch data
|
|
220
|
-
...c.refreshEvents.map((evt) => ({
|
|
221
|
-
from: "browsing",
|
|
222
|
-
to: "browsing",
|
|
223
|
-
event: evt,
|
|
224
|
-
effects: [["ref", entityName]]
|
|
225
|
-
}))
|
|
213
|
+
}
|
|
226
214
|
]
|
|
227
215
|
}
|
|
228
216
|
};
|
|
@@ -280,6 +268,8 @@ function resolve2(params) {
|
|
|
280
268
|
}
|
|
281
269
|
]
|
|
282
270
|
};
|
|
271
|
+
const saveEvent = params.saveEvent ?? "SAVE";
|
|
272
|
+
const emitOnSave = params.emitOnSave ?? saveEvent;
|
|
283
273
|
return {
|
|
284
274
|
entityName,
|
|
285
275
|
fields,
|
|
@@ -293,9 +283,9 @@ function resolve2(params) {
|
|
|
293
283
|
openPayload: params.openPayload ?? [],
|
|
294
284
|
closeEvent: params.closeEvent ?? "CLOSE",
|
|
295
285
|
openEffects: params.openEffects ?? [],
|
|
296
|
-
saveEvent
|
|
286
|
+
saveEvent,
|
|
297
287
|
saveEffects: params.saveEffects ?? [],
|
|
298
|
-
emitOnSave
|
|
288
|
+
emitOnSave,
|
|
299
289
|
standalone: params.standalone ?? true,
|
|
300
290
|
pageName: params.pageName ?? `${entityName}ModalPage`,
|
|
301
291
|
pagePath: params.pagePath ?? `/${p.toLowerCase()}/modal`,
|
|
@@ -309,11 +299,9 @@ function buildTrait2(c) {
|
|
|
309
299
|
const events = [
|
|
310
300
|
{ key: "INIT", name: "Initialize" },
|
|
311
301
|
{ key: c.openEvent, name: "Open", ...c.openPayload.length > 0 ? { payload: c.openPayload } : {} },
|
|
312
|
-
{ key: c.closeEvent, name: "Close" }
|
|
302
|
+
{ key: c.closeEvent, name: "Close" },
|
|
303
|
+
{ key: c.saveEvent, name: "Save", payload: [{ name: "data", type: "object", required: true }] }
|
|
313
304
|
];
|
|
314
|
-
if (c.saveEvent) {
|
|
315
|
-
events.push({ key: c.saveEvent, name: "Save", payload: [{ name: "data", type: "object", required: true }] });
|
|
316
|
-
}
|
|
317
305
|
const transitions = [
|
|
318
306
|
// INIT: closed → closed
|
|
319
307
|
{
|
|
@@ -366,41 +354,44 @@ function buildTrait2(c) {
|
|
|
366
354
|
}]] : []
|
|
367
355
|
] }
|
|
368
356
|
];
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
children: [
|
|
375
|
-
{ type: "stack", direction: "horizontal", gap: "md",
|
|
376
|
-
{ type: "
|
|
377
|
-
|
|
378
|
-
{ type: "typography", content: c.modalTitle, variant: "h2" }
|
|
379
|
-
] },
|
|
380
|
-
{ type: "button", label: "Open", event: c.openEvent, variant: "primary", icon: c.headerIcon }
|
|
357
|
+
const mainRefresh = c.standalone ? [["ref", c.entityName], ["render-ui", "main", {
|
|
358
|
+
type: "stack",
|
|
359
|
+
direction: "vertical",
|
|
360
|
+
gap: "lg",
|
|
361
|
+
children: [
|
|
362
|
+
{ type: "stack", direction: "horizontal", gap: "md", justify: "space-between", children: [
|
|
363
|
+
{ type: "stack", direction: "horizontal", gap: "md", children: [
|
|
364
|
+
{ type: "icon", name: c.headerIcon, size: "lg" },
|
|
365
|
+
{ type: "typography", content: c.modalTitle, variant: "h2" }
|
|
381
366
|
] },
|
|
382
|
-
{ type: "
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
367
|
+
{ type: "button", label: "Open", event: c.openEvent, variant: "primary", icon: c.headerIcon }
|
|
368
|
+
] },
|
|
369
|
+
{ type: "divider" },
|
|
370
|
+
{ type: "empty-state", icon: c.headerIcon, title: "Nothing open", description: "Click Open to view details in a modal overlay." }
|
|
371
|
+
]
|
|
372
|
+
}]] : [];
|
|
373
|
+
transitions.push({
|
|
374
|
+
from: "open",
|
|
375
|
+
to: "closed",
|
|
376
|
+
event: c.saveEvent,
|
|
377
|
+
effects: [
|
|
378
|
+
...c.saveEffects,
|
|
379
|
+
["render-ui", "modal", null],
|
|
380
|
+
// Emit after persist succeeds so browse traits can fetch fresh data.
|
|
381
|
+
// Skip the emit when emitOnSave equals saveEvent — that's a self-emit
|
|
382
|
+
// that the runtime would short-circuit anyway, and avoids double
|
|
383
|
+
// dispatch on every save.
|
|
384
|
+
...c.emitOnSave !== c.saveEvent ? [["emit", c.emitOnSave]] : [],
|
|
385
|
+
...mainRefresh
|
|
386
|
+
]
|
|
387
|
+
});
|
|
399
388
|
return {
|
|
400
389
|
name: c.traitName,
|
|
401
390
|
linkedEntity: c.entityName,
|
|
402
391
|
category: "interaction",
|
|
403
|
-
|
|
392
|
+
// Phase F.10: emits[] is always populated (default emitOnSave = saveEvent).
|
|
393
|
+
// If a molecule supplies a distinct emitOnSave, declare both events.
|
|
394
|
+
emits: c.emitOnSave === c.saveEvent ? [{ event: c.saveEvent }] : [{ event: c.saveEvent }, { event: c.emitOnSave }],
|
|
404
395
|
stateMachine: {
|
|
405
396
|
states: [{ name: "closed", isInitial: true }, { name: "open" }],
|
|
406
397
|
events,
|
|
@@ -429,6 +420,8 @@ function resolve3(params) {
|
|
|
429
420
|
const fields = ensureIdField(params.fields);
|
|
430
421
|
const nonIdFields = fields.filter((f) => f.name !== "id");
|
|
431
422
|
const p = plural(entityName);
|
|
423
|
+
const confirmEvent = params.confirmEvent ?? "CONFIRM";
|
|
424
|
+
const emitOnConfirm = params.emitOnConfirm ?? confirmEvent;
|
|
432
425
|
return {
|
|
433
426
|
entityName,
|
|
434
427
|
fields,
|
|
@@ -442,9 +435,9 @@ function resolve3(params) {
|
|
|
442
435
|
cancelLabel: params.cancelLabel ?? "Cancel",
|
|
443
436
|
headerIcon: params.headerIcon ?? "shield-check",
|
|
444
437
|
requestEvent: params.requestEvent ?? "REQUEST",
|
|
445
|
-
confirmEvent
|
|
438
|
+
confirmEvent,
|
|
446
439
|
confirmEffects: params.confirmEffects ?? [],
|
|
447
|
-
emitOnConfirm
|
|
440
|
+
emitOnConfirm,
|
|
448
441
|
standalone: params.standalone ?? true,
|
|
449
442
|
pageName: params.pageName ?? `${entityName}ConfirmPage`,
|
|
450
443
|
pagePath: params.pagePath ?? `/${p.toLowerCase()}/confirm`,
|
|
@@ -524,7 +517,9 @@ function buildTrait3(c) {
|
|
|
524
517
|
name: c.traitName,
|
|
525
518
|
linkedEntity: entityName,
|
|
526
519
|
category: "interaction",
|
|
527
|
-
|
|
520
|
+
// Phase F.10: emits[] always populated. When emitOnConfirm equals
|
|
521
|
+
// confirmEvent, declare just the one. When they differ, declare both.
|
|
522
|
+
emits: c.emitOnConfirm === c.confirmEvent ? [{ event: c.confirmEvent }] : [{ event: c.confirmEvent }, { event: c.emitOnConfirm }],
|
|
528
523
|
stateMachine: {
|
|
529
524
|
states: [
|
|
530
525
|
{ name: "idle", isInitial: true },
|
|
@@ -561,7 +556,9 @@ function buildTrait3(c) {
|
|
|
561
556
|
effects: [
|
|
562
557
|
...c.confirmEffects,
|
|
563
558
|
...dismissAndRefresh,
|
|
564
|
-
|
|
559
|
+
// Skip self-emit when emitOnConfirm == confirmEvent (the runtime
|
|
560
|
+
// would short-circuit anyway).
|
|
561
|
+
...c.emitOnConfirm !== c.confirmEvent ? [["emit", c.emitOnConfirm]] : []
|
|
565
562
|
]
|
|
566
563
|
},
|
|
567
564
|
{
|
|
@@ -8420,6 +8417,7 @@ function stdList(params) {
|
|
|
8420
8417
|
const UPPER = entityName.replace(/([a-z])([A-Z])/g, "$1_$2").toUpperCase();
|
|
8421
8418
|
const CREATED = `${UPPER}_CREATED`;
|
|
8422
8419
|
const UPDATED = `${UPPER}_UPDATED`;
|
|
8420
|
+
const DELETED = `${UPPER}_DELETED`;
|
|
8423
8421
|
const browseTrait = extractTrait(stdBrowse({
|
|
8424
8422
|
entityName,
|
|
8425
8423
|
fields,
|
|
@@ -8440,7 +8438,7 @@ function stdList(params) {
|
|
|
8440
8438
|
{ label: "Edit", event: "EDIT" },
|
|
8441
8439
|
{ label: "Delete", event: "DELETE", variant: "danger" }
|
|
8442
8440
|
],
|
|
8443
|
-
refreshEvents: [CREATED, UPDATED]
|
|
8441
|
+
refreshEvents: [CREATED, UPDATED, DELETED]
|
|
8444
8442
|
}));
|
|
8445
8443
|
const createTrait = extractTrait(stdModal({
|
|
8446
8444
|
standalone: false,
|
|
@@ -8486,62 +8484,20 @@ function stdList(params) {
|
|
|
8486
8484
|
closeEvent: "CLOSE",
|
|
8487
8485
|
openEffects: [["fetch", entityName, { id: "@payload.id" }]]
|
|
8488
8486
|
}));
|
|
8489
|
-
const
|
|
8490
|
-
|
|
8491
|
-
|
|
8492
|
-
|
|
8493
|
-
|
|
8494
|
-
|
|
8495
|
-
|
|
8496
|
-
|
|
8497
|
-
|
|
8498
|
-
|
|
8499
|
-
|
|
8500
|
-
|
|
8501
|
-
|
|
8502
|
-
);
|
|
8503
|
-
const browseMainView = initRenderEffect ? initRenderEffect[2] : null;
|
|
8504
|
-
sm.transitions.push(
|
|
8505
|
-
// DELETE: browsing → deleting (fetch entity by ID, show confirmation modal)
|
|
8506
|
-
{ from: "browsing", to: "deleting", event: "DELETE", effects: [
|
|
8507
|
-
["fetch", entityName, { id: "@payload.id" }],
|
|
8508
|
-
["render-ui", "modal", {
|
|
8509
|
-
type: "stack",
|
|
8510
|
-
direction: "vertical",
|
|
8511
|
-
gap: "md",
|
|
8512
|
-
children: [
|
|
8513
|
-
{ type: "stack", direction: "horizontal", gap: "sm", children: [
|
|
8514
|
-
{ type: "icon", name: "trash-2", size: "md" },
|
|
8515
|
-
{ type: "typography", content: `Delete ${entityName}`, variant: "h3" }
|
|
8516
|
-
] },
|
|
8517
|
-
{ type: "divider" },
|
|
8518
|
-
{ type: "typography", content: `@entity.${c.nonIdFields[0]?.name ?? "name"}`, variant: "h4" },
|
|
8519
|
-
{ type: "typography", content: c.deleteMessage, variant: "body" },
|
|
8520
|
-
{ type: "stack", direction: "horizontal", gap: "sm", justify: "end", children: [
|
|
8521
|
-
{ type: "button", label: "Cancel", event: "CANCEL", variant: "ghost" },
|
|
8522
|
-
{ type: "button", label: "Delete", event: "CONFIRM_DELETE", variant: "danger", icon: "trash" }
|
|
8523
|
-
] }
|
|
8524
|
-
]
|
|
8525
|
-
}]
|
|
8526
|
-
] },
|
|
8527
|
-
// CONFIRM_DELETE: deleting → browsing (persist delete, dismiss modal, re-render main)
|
|
8528
|
-
{ from: "deleting", to: "browsing", event: "CONFIRM_DELETE", effects: [
|
|
8529
|
-
["persist", "delete", entityName, "@entity.id"],
|
|
8530
|
-
["render-ui", "modal", null],
|
|
8531
|
-
["render-ui", "main", browseMainView]
|
|
8532
|
-
] },
|
|
8533
|
-
// CANCEL/CLOSE from deleting (dismiss modal, re-render main)
|
|
8534
|
-
{ from: "deleting", to: "browsing", event: "CANCEL", effects: [
|
|
8535
|
-
["render-ui", "modal", null],
|
|
8536
|
-
["fetch", entityName],
|
|
8537
|
-
["render-ui", "main", browseMainView]
|
|
8538
|
-
] },
|
|
8539
|
-
{ from: "deleting", to: "browsing", event: "CLOSE", effects: [
|
|
8540
|
-
["render-ui", "modal", null],
|
|
8541
|
-
["fetch", entityName],
|
|
8542
|
-
["render-ui", "main", browseMainView]
|
|
8543
|
-
] }
|
|
8544
|
-
);
|
|
8487
|
+
const deleteTrait = extractTrait(stdConfirmation({
|
|
8488
|
+
standalone: false,
|
|
8489
|
+
entityName,
|
|
8490
|
+
fields,
|
|
8491
|
+
traitName: `${entityName}Delete`,
|
|
8492
|
+
confirmTitle: `Delete ${entityName}`,
|
|
8493
|
+
confirmMessage: c.deleteMessage,
|
|
8494
|
+
confirmLabel: "Delete",
|
|
8495
|
+
headerIcon: "trash-2",
|
|
8496
|
+
requestEvent: "DELETE",
|
|
8497
|
+
confirmEvent: "CONFIRM_DELETE",
|
|
8498
|
+
confirmEffects: [["persist", "delete", entityName, "@entity.pendingId"]],
|
|
8499
|
+
emitOnConfirm: DELETED
|
|
8500
|
+
}));
|
|
8545
8501
|
const entity = makeEntity({ name: entityName, fields, persistence: c.persistence, collection: c.collection });
|
|
8546
8502
|
const page = {
|
|
8547
8503
|
name: c.pageName,
|
|
@@ -8551,13 +8507,14 @@ function stdList(params) {
|
|
|
8551
8507
|
{ ref: browseTrait.name },
|
|
8552
8508
|
{ ref: createTrait.name },
|
|
8553
8509
|
{ ref: editTrait.name },
|
|
8554
|
-
{ ref: viewTrait.name }
|
|
8510
|
+
{ ref: viewTrait.name },
|
|
8511
|
+
{ ref: deleteTrait.name }
|
|
8555
8512
|
]
|
|
8556
8513
|
};
|
|
8557
8514
|
return {
|
|
8558
8515
|
name: `${entityName}Orbital`,
|
|
8559
8516
|
entity,
|
|
8560
|
-
traits: [browseTrait, createTrait, editTrait, viewTrait],
|
|
8517
|
+
traits: [browseTrait, createTrait, editTrait, viewTrait, deleteTrait],
|
|
8561
8518
|
pages: [page]
|
|
8562
8519
|
};
|
|
8563
8520
|
}
|
|
@@ -9045,17 +9002,9 @@ function stdInventory(params) {
|
|
|
9045
9002
|
headerIcon: "trash-2",
|
|
9046
9003
|
requestEvent: "DROP",
|
|
9047
9004
|
confirmEvent: "CONFIRM_DROP",
|
|
9048
|
-
confirmEffects: [["persist", "delete", entityName, "@
|
|
9005
|
+
confirmEffects: [["persist", "delete", entityName, "@entity.pendingId"]],
|
|
9049
9006
|
emitOnConfirm: "CONFIRM_DROP"
|
|
9050
9007
|
}));
|
|
9051
|
-
const dropSm = dropTrait.stateMachine;
|
|
9052
|
-
if (dropSm && "events" in dropSm) {
|
|
9053
|
-
const events = dropSm.events;
|
|
9054
|
-
const confirmDropEvt = events.find((e) => e.key === "CONFIRM_DROP");
|
|
9055
|
-
if (confirmDropEvt && !confirmDropEvt.payload) {
|
|
9056
|
-
confirmDropEvt.payload = [{ name: "id", type: "string", required: true }];
|
|
9057
|
-
}
|
|
9058
|
-
}
|
|
9059
9008
|
const instances = [
|
|
9060
9009
|
{ id: "item-1", name: "Health Potion", description: "Restores 50 HP", status: "active", pendingId: "" },
|
|
9061
9010
|
{ id: "item-2", name: "Iron Sword", description: "A sturdy blade", status: "active", pendingId: "" },
|