@almadar/std 4.0.0 → 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/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/index.js +71 -122
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4785,19 +4785,14 @@ function buildTrait(c) {
|
|
|
4785
4785
|
const actionEvents = /* @__PURE__ */ new Set();
|
|
4786
4786
|
for (const a of c.headerActions) actionEvents.add(a.event);
|
|
4787
4787
|
for (const a of c.itemActions) actionEvents.add(a.event);
|
|
4788
|
-
for (const re of c.refreshEvents) actionEvents.add(re);
|
|
4789
4788
|
const events = [
|
|
4790
4789
|
{ key: "INIT", name: "Initialize" },
|
|
4791
4790
|
...Array.from(actionEvents).map((e) => {
|
|
4792
4791
|
const needsId = c.itemActions.some((a) => a.event === e);
|
|
4793
|
-
const isRefresh = c.refreshEvents.includes(e);
|
|
4794
|
-
if (isRefresh) {
|
|
4795
|
-
return { key: e, name: e, payload: [{ name: "data", type: "object", required: true }] };
|
|
4796
|
-
}
|
|
4797
4792
|
return needsId ? { key: e, name: e, payload: [{ name: "id", type: "string", required: true }, { name: "row", type: "object" }] } : { key: e, name: e };
|
|
4798
4793
|
})
|
|
4799
4794
|
];
|
|
4800
|
-
const listensDecl = c.refreshEvents.length > 0 ? c.refreshEvents.map((evt) => ({ event: evt, triggers:
|
|
4795
|
+
const listensDecl = c.refreshEvents.length > 0 ? c.refreshEvents.map((evt) => ({ event: evt, triggers: "INIT" })) : void 0;
|
|
4801
4796
|
return {
|
|
4802
4797
|
name: c.traitName,
|
|
4803
4798
|
linkedEntity: entityName,
|
|
@@ -4834,14 +4829,7 @@ function buildTrait(c) {
|
|
|
4834
4829
|
]
|
|
4835
4830
|
}]
|
|
4836
4831
|
]
|
|
4837
|
-
}
|
|
4838
|
-
// Refresh self-loops: when modal atoms fire SAVE etc., re-fetch data
|
|
4839
|
-
...c.refreshEvents.map((evt) => ({
|
|
4840
|
-
from: "browsing",
|
|
4841
|
-
to: "browsing",
|
|
4842
|
-
event: evt,
|
|
4843
|
-
effects: [["ref", entityName]]
|
|
4844
|
-
}))
|
|
4832
|
+
}
|
|
4845
4833
|
]
|
|
4846
4834
|
}
|
|
4847
4835
|
};
|
|
@@ -4899,6 +4887,8 @@ function resolve2(params) {
|
|
|
4899
4887
|
}
|
|
4900
4888
|
]
|
|
4901
4889
|
};
|
|
4890
|
+
const saveEvent = params.saveEvent ?? "SAVE";
|
|
4891
|
+
const emitOnSave = params.emitOnSave ?? saveEvent;
|
|
4902
4892
|
return {
|
|
4903
4893
|
entityName,
|
|
4904
4894
|
fields,
|
|
@@ -4912,9 +4902,9 @@ function resolve2(params) {
|
|
|
4912
4902
|
openPayload: params.openPayload ?? [],
|
|
4913
4903
|
closeEvent: params.closeEvent ?? "CLOSE",
|
|
4914
4904
|
openEffects: params.openEffects ?? [],
|
|
4915
|
-
saveEvent
|
|
4905
|
+
saveEvent,
|
|
4916
4906
|
saveEffects: params.saveEffects ?? [],
|
|
4917
|
-
emitOnSave
|
|
4907
|
+
emitOnSave,
|
|
4918
4908
|
standalone: params.standalone ?? true,
|
|
4919
4909
|
pageName: params.pageName ?? `${entityName}ModalPage`,
|
|
4920
4910
|
pagePath: params.pagePath ?? `/${p.toLowerCase()}/modal`,
|
|
@@ -4928,11 +4918,9 @@ function buildTrait2(c) {
|
|
|
4928
4918
|
const events = [
|
|
4929
4919
|
{ key: "INIT", name: "Initialize" },
|
|
4930
4920
|
{ key: c.openEvent, name: "Open", ...c.openPayload.length > 0 ? { payload: c.openPayload } : {} },
|
|
4931
|
-
{ key: c.closeEvent, name: "Close" }
|
|
4921
|
+
{ key: c.closeEvent, name: "Close" },
|
|
4922
|
+
{ key: c.saveEvent, name: "Save", payload: [{ name: "data", type: "object", required: true }] }
|
|
4932
4923
|
];
|
|
4933
|
-
if (c.saveEvent) {
|
|
4934
|
-
events.push({ key: c.saveEvent, name: "Save", payload: [{ name: "data", type: "object", required: true }] });
|
|
4935
|
-
}
|
|
4936
4924
|
const transitions = [
|
|
4937
4925
|
// INIT: closed → closed
|
|
4938
4926
|
{
|
|
@@ -4985,41 +4973,44 @@ function buildTrait2(c) {
|
|
|
4985
4973
|
}]] : []
|
|
4986
4974
|
] }
|
|
4987
4975
|
];
|
|
4988
|
-
|
|
4989
|
-
|
|
4990
|
-
|
|
4991
|
-
|
|
4992
|
-
|
|
4993
|
-
children: [
|
|
4994
|
-
{ type: "stack", direction: "horizontal", gap: "md",
|
|
4995
|
-
{ type: "
|
|
4996
|
-
|
|
4997
|
-
{ type: "typography", content: c.modalTitle, variant: "h2" }
|
|
4998
|
-
] },
|
|
4999
|
-
{ type: "button", label: "Open", event: c.openEvent, variant: "primary", icon: c.headerIcon }
|
|
4976
|
+
const mainRefresh = c.standalone ? [["ref", c.entityName], ["render-ui", "main", {
|
|
4977
|
+
type: "stack",
|
|
4978
|
+
direction: "vertical",
|
|
4979
|
+
gap: "lg",
|
|
4980
|
+
children: [
|
|
4981
|
+
{ type: "stack", direction: "horizontal", gap: "md", justify: "space-between", children: [
|
|
4982
|
+
{ type: "stack", direction: "horizontal", gap: "md", children: [
|
|
4983
|
+
{ type: "icon", name: c.headerIcon, size: "lg" },
|
|
4984
|
+
{ type: "typography", content: c.modalTitle, variant: "h2" }
|
|
5000
4985
|
] },
|
|
5001
|
-
{ type: "
|
|
5002
|
-
|
|
5003
|
-
|
|
5004
|
-
|
|
5005
|
-
|
|
5006
|
-
|
|
5007
|
-
|
|
5008
|
-
|
|
5009
|
-
|
|
5010
|
-
|
|
5011
|
-
|
|
5012
|
-
|
|
5013
|
-
|
|
5014
|
-
|
|
5015
|
-
|
|
5016
|
-
|
|
5017
|
-
|
|
4986
|
+
{ type: "button", label: "Open", event: c.openEvent, variant: "primary", icon: c.headerIcon }
|
|
4987
|
+
] },
|
|
4988
|
+
{ type: "divider" },
|
|
4989
|
+
{ type: "empty-state", icon: c.headerIcon, title: "Nothing open", description: "Click Open to view details in a modal overlay." }
|
|
4990
|
+
]
|
|
4991
|
+
}]] : [];
|
|
4992
|
+
transitions.push({
|
|
4993
|
+
from: "open",
|
|
4994
|
+
to: "closed",
|
|
4995
|
+
event: c.saveEvent,
|
|
4996
|
+
effects: [
|
|
4997
|
+
...c.saveEffects,
|
|
4998
|
+
["render-ui", "modal", null],
|
|
4999
|
+
// Emit after persist succeeds so browse traits can fetch fresh data.
|
|
5000
|
+
// Skip the emit when emitOnSave equals saveEvent — that's a self-emit
|
|
5001
|
+
// that the runtime would short-circuit anyway, and avoids double
|
|
5002
|
+
// dispatch on every save.
|
|
5003
|
+
...c.emitOnSave !== c.saveEvent ? [["emit", c.emitOnSave]] : [],
|
|
5004
|
+
...mainRefresh
|
|
5005
|
+
]
|
|
5006
|
+
});
|
|
5018
5007
|
return {
|
|
5019
5008
|
name: c.traitName,
|
|
5020
5009
|
linkedEntity: c.entityName,
|
|
5021
5010
|
category: "interaction",
|
|
5022
|
-
|
|
5011
|
+
// Phase F.10: emits[] is always populated (default emitOnSave = saveEvent).
|
|
5012
|
+
// If a molecule supplies a distinct emitOnSave, declare both events.
|
|
5013
|
+
emits: c.emitOnSave === c.saveEvent ? [{ event: c.saveEvent }] : [{ event: c.saveEvent }, { event: c.emitOnSave }],
|
|
5023
5014
|
stateMachine: {
|
|
5024
5015
|
states: [{ name: "closed", isInitial: true }, { name: "open" }],
|
|
5025
5016
|
events,
|
|
@@ -5048,6 +5039,8 @@ function resolve3(params) {
|
|
|
5048
5039
|
const fields = ensureIdField(params.fields);
|
|
5049
5040
|
const nonIdFields = fields.filter((f) => f.name !== "id");
|
|
5050
5041
|
const p = plural(entityName);
|
|
5042
|
+
const confirmEvent = params.confirmEvent ?? "CONFIRM";
|
|
5043
|
+
const emitOnConfirm = params.emitOnConfirm ?? confirmEvent;
|
|
5051
5044
|
return {
|
|
5052
5045
|
entityName,
|
|
5053
5046
|
fields,
|
|
@@ -5061,9 +5054,9 @@ function resolve3(params) {
|
|
|
5061
5054
|
cancelLabel: params.cancelLabel ?? "Cancel",
|
|
5062
5055
|
headerIcon: params.headerIcon ?? "shield-check",
|
|
5063
5056
|
requestEvent: params.requestEvent ?? "REQUEST",
|
|
5064
|
-
confirmEvent
|
|
5057
|
+
confirmEvent,
|
|
5065
5058
|
confirmEffects: params.confirmEffects ?? [],
|
|
5066
|
-
emitOnConfirm
|
|
5059
|
+
emitOnConfirm,
|
|
5067
5060
|
standalone: params.standalone ?? true,
|
|
5068
5061
|
pageName: params.pageName ?? `${entityName}ConfirmPage`,
|
|
5069
5062
|
pagePath: params.pagePath ?? `/${p.toLowerCase()}/confirm`,
|
|
@@ -5143,7 +5136,9 @@ function buildTrait3(c) {
|
|
|
5143
5136
|
name: c.traitName,
|
|
5144
5137
|
linkedEntity: entityName,
|
|
5145
5138
|
category: "interaction",
|
|
5146
|
-
|
|
5139
|
+
// Phase F.10: emits[] always populated. When emitOnConfirm equals
|
|
5140
|
+
// confirmEvent, declare just the one. When they differ, declare both.
|
|
5141
|
+
emits: c.emitOnConfirm === c.confirmEvent ? [{ event: c.confirmEvent }] : [{ event: c.confirmEvent }, { event: c.emitOnConfirm }],
|
|
5147
5142
|
stateMachine: {
|
|
5148
5143
|
states: [
|
|
5149
5144
|
{ name: "idle", isInitial: true },
|
|
@@ -5180,7 +5175,9 @@ function buildTrait3(c) {
|
|
|
5180
5175
|
effects: [
|
|
5181
5176
|
...c.confirmEffects,
|
|
5182
5177
|
...dismissAndRefresh,
|
|
5183
|
-
|
|
5178
|
+
// Skip self-emit when emitOnConfirm == confirmEvent (the runtime
|
|
5179
|
+
// would short-circuit anyway).
|
|
5180
|
+
...c.emitOnConfirm !== c.confirmEvent ? [["emit", c.emitOnConfirm]] : []
|
|
5184
5181
|
]
|
|
5185
5182
|
},
|
|
5186
5183
|
{
|
|
@@ -13039,6 +13036,7 @@ function stdList(params) {
|
|
|
13039
13036
|
const UPPER = entityName.replace(/([a-z])([A-Z])/g, "$1_$2").toUpperCase();
|
|
13040
13037
|
const CREATED = `${UPPER}_CREATED`;
|
|
13041
13038
|
const UPDATED = `${UPPER}_UPDATED`;
|
|
13039
|
+
const DELETED = `${UPPER}_DELETED`;
|
|
13042
13040
|
const browseTrait = extractTrait(stdBrowse({
|
|
13043
13041
|
entityName,
|
|
13044
13042
|
fields,
|
|
@@ -13059,7 +13057,7 @@ function stdList(params) {
|
|
|
13059
13057
|
{ label: "Edit", event: "EDIT" },
|
|
13060
13058
|
{ label: "Delete", event: "DELETE", variant: "danger" }
|
|
13061
13059
|
],
|
|
13062
|
-
refreshEvents: [CREATED, UPDATED]
|
|
13060
|
+
refreshEvents: [CREATED, UPDATED, DELETED]
|
|
13063
13061
|
}));
|
|
13064
13062
|
const createTrait = extractTrait(stdModal({
|
|
13065
13063
|
standalone: false,
|
|
@@ -13105,62 +13103,20 @@ function stdList(params) {
|
|
|
13105
13103
|
closeEvent: "CLOSE",
|
|
13106
13104
|
openEffects: [["fetch", entityName, { id: "@payload.id" }]]
|
|
13107
13105
|
}));
|
|
13108
|
-
const
|
|
13109
|
-
|
|
13110
|
-
|
|
13111
|
-
|
|
13112
|
-
|
|
13113
|
-
|
|
13114
|
-
|
|
13115
|
-
|
|
13116
|
-
|
|
13117
|
-
|
|
13118
|
-
|
|
13119
|
-
|
|
13120
|
-
|
|
13121
|
-
);
|
|
13122
|
-
const browseMainView = initRenderEffect ? initRenderEffect[2] : null;
|
|
13123
|
-
sm.transitions.push(
|
|
13124
|
-
// DELETE: browsing → deleting (fetch entity by ID, show confirmation modal)
|
|
13125
|
-
{ from: "browsing", to: "deleting", event: "DELETE", effects: [
|
|
13126
|
-
["fetch", entityName, { id: "@payload.id" }],
|
|
13127
|
-
["render-ui", "modal", {
|
|
13128
|
-
type: "stack",
|
|
13129
|
-
direction: "vertical",
|
|
13130
|
-
gap: "md",
|
|
13131
|
-
children: [
|
|
13132
|
-
{ type: "stack", direction: "horizontal", gap: "sm", children: [
|
|
13133
|
-
{ type: "icon", name: "trash-2", size: "md" },
|
|
13134
|
-
{ type: "typography", content: `Delete ${entityName}`, variant: "h3" }
|
|
13135
|
-
] },
|
|
13136
|
-
{ type: "divider" },
|
|
13137
|
-
{ type: "typography", content: `@entity.${c.nonIdFields[0]?.name ?? "name"}`, variant: "h4" },
|
|
13138
|
-
{ type: "typography", content: c.deleteMessage, variant: "body" },
|
|
13139
|
-
{ type: "stack", direction: "horizontal", gap: "sm", justify: "end", children: [
|
|
13140
|
-
{ type: "button", label: "Cancel", event: "CANCEL", variant: "ghost" },
|
|
13141
|
-
{ type: "button", label: "Delete", event: "CONFIRM_DELETE", variant: "danger", icon: "trash" }
|
|
13142
|
-
] }
|
|
13143
|
-
]
|
|
13144
|
-
}]
|
|
13145
|
-
] },
|
|
13146
|
-
// CONFIRM_DELETE: deleting → browsing (persist delete, dismiss modal, re-render main)
|
|
13147
|
-
{ from: "deleting", to: "browsing", event: "CONFIRM_DELETE", effects: [
|
|
13148
|
-
["persist", "delete", entityName, "@entity.id"],
|
|
13149
|
-
["render-ui", "modal", null],
|
|
13150
|
-
["render-ui", "main", browseMainView]
|
|
13151
|
-
] },
|
|
13152
|
-
// CANCEL/CLOSE from deleting (dismiss modal, re-render main)
|
|
13153
|
-
{ from: "deleting", to: "browsing", event: "CANCEL", effects: [
|
|
13154
|
-
["render-ui", "modal", null],
|
|
13155
|
-
["fetch", entityName],
|
|
13156
|
-
["render-ui", "main", browseMainView]
|
|
13157
|
-
] },
|
|
13158
|
-
{ from: "deleting", to: "browsing", event: "CLOSE", effects: [
|
|
13159
|
-
["render-ui", "modal", null],
|
|
13160
|
-
["fetch", entityName],
|
|
13161
|
-
["render-ui", "main", browseMainView]
|
|
13162
|
-
] }
|
|
13163
|
-
);
|
|
13106
|
+
const deleteTrait = extractTrait(stdConfirmation({
|
|
13107
|
+
standalone: false,
|
|
13108
|
+
entityName,
|
|
13109
|
+
fields,
|
|
13110
|
+
traitName: `${entityName}Delete`,
|
|
13111
|
+
confirmTitle: `Delete ${entityName}`,
|
|
13112
|
+
confirmMessage: c.deleteMessage,
|
|
13113
|
+
confirmLabel: "Delete",
|
|
13114
|
+
headerIcon: "trash-2",
|
|
13115
|
+
requestEvent: "DELETE",
|
|
13116
|
+
confirmEvent: "CONFIRM_DELETE",
|
|
13117
|
+
confirmEffects: [["persist", "delete", entityName, "@entity.pendingId"]],
|
|
13118
|
+
emitOnConfirm: DELETED
|
|
13119
|
+
}));
|
|
13164
13120
|
const entity = makeEntity({ name: entityName, fields, persistence: c.persistence, collection: c.collection });
|
|
13165
13121
|
const page = {
|
|
13166
13122
|
name: c.pageName,
|
|
@@ -13170,13 +13126,14 @@ function stdList(params) {
|
|
|
13170
13126
|
{ ref: browseTrait.name },
|
|
13171
13127
|
{ ref: createTrait.name },
|
|
13172
13128
|
{ ref: editTrait.name },
|
|
13173
|
-
{ ref: viewTrait.name }
|
|
13129
|
+
{ ref: viewTrait.name },
|
|
13130
|
+
{ ref: deleteTrait.name }
|
|
13174
13131
|
]
|
|
13175
13132
|
};
|
|
13176
13133
|
return {
|
|
13177
13134
|
name: `${entityName}Orbital`,
|
|
13178
13135
|
entity,
|
|
13179
|
-
traits: [browseTrait, createTrait, editTrait, viewTrait],
|
|
13136
|
+
traits: [browseTrait, createTrait, editTrait, viewTrait, deleteTrait],
|
|
13180
13137
|
pages: [page]
|
|
13181
13138
|
};
|
|
13182
13139
|
}
|
|
@@ -13664,17 +13621,9 @@ function stdInventory(params) {
|
|
|
13664
13621
|
headerIcon: "trash-2",
|
|
13665
13622
|
requestEvent: "DROP",
|
|
13666
13623
|
confirmEvent: "CONFIRM_DROP",
|
|
13667
|
-
confirmEffects: [["persist", "delete", entityName, "@
|
|
13624
|
+
confirmEffects: [["persist", "delete", entityName, "@entity.pendingId"]],
|
|
13668
13625
|
emitOnConfirm: "CONFIRM_DROP"
|
|
13669
13626
|
}));
|
|
13670
|
-
const dropSm = dropTrait.stateMachine;
|
|
13671
|
-
if (dropSm && "events" in dropSm) {
|
|
13672
|
-
const events = dropSm.events;
|
|
13673
|
-
const confirmDropEvt = events.find((e) => e.key === "CONFIRM_DROP");
|
|
13674
|
-
if (confirmDropEvt && !confirmDropEvt.payload) {
|
|
13675
|
-
confirmDropEvt.payload = [{ name: "id", type: "string", required: true }];
|
|
13676
|
-
}
|
|
13677
|
-
}
|
|
13678
13627
|
const instances = [
|
|
13679
13628
|
{ id: "item-1", name: "Health Potion", description: "Restores 50 HP", status: "active", pendingId: "" },
|
|
13680
13629
|
{ id: "item-2", name: "Iron Sword", description: "A sturdy blade", status: "active", pendingId: "" },
|