@mmapp/react 0.1.0-alpha.3 → 0.1.0-alpha.9
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/index.d.mts +1352 -93
- package/dist/index.d.ts +1352 -93
- package/dist/index.js +1032 -1314
- package/dist/index.mjs +981 -1301
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -32,6 +32,7 @@ var index_exports = {};
|
|
|
32
32
|
__export(index_exports, {
|
|
33
33
|
Accordion: () => Accordion,
|
|
34
34
|
AnimatedBox: () => AnimatedBox,
|
|
35
|
+
BUILT_IN_CONSTRAINTS: () => BUILT_IN_CONSTRAINTS,
|
|
35
36
|
Badge: () => Badge,
|
|
36
37
|
Blueprint: () => Blueprint,
|
|
37
38
|
BrowserPlayer: () => BrowserPlayer,
|
|
@@ -58,6 +59,7 @@ __export(index_exports, {
|
|
|
58
59
|
Modal: () => Modal,
|
|
59
60
|
ModelBuilder: () => ModelBuilder,
|
|
60
61
|
NavLink: () => NavLink,
|
|
62
|
+
ORCHESTRATION_PRESETS: () => ORCHESTRATION_PRESETS,
|
|
61
63
|
PlayerProvider: () => PlayerProvider,
|
|
62
64
|
RoleGuard: () => RoleGuard,
|
|
63
65
|
Route: () => Route,
|
|
@@ -81,12 +83,19 @@ __export(index_exports, {
|
|
|
81
83
|
WorkflowProvider: () => WorkflowProvider,
|
|
82
84
|
WorkflowRuntime: () => WorkflowRuntime,
|
|
83
85
|
action: () => action,
|
|
84
|
-
|
|
86
|
+
actor: () => actor,
|
|
87
|
+
after: () => after,
|
|
88
|
+
allowTransition: () => allowTransition,
|
|
89
|
+
and: () => and,
|
|
85
90
|
applyMixins: () => applyMixins,
|
|
86
91
|
approval: () => approval,
|
|
87
92
|
assertModelValid: () => assertModelValid,
|
|
88
93
|
cedar: () => cedar,
|
|
94
|
+
compose: () => compose,
|
|
95
|
+
computeVisibility: () => computeVisibility,
|
|
96
|
+
configureActor: () => configureActor,
|
|
89
97
|
connector: () => connector,
|
|
98
|
+
constraints: () => constraints,
|
|
90
99
|
createActions: () => createActions,
|
|
91
100
|
createCRUD: () => createCRUD,
|
|
92
101
|
createLocalDataResolver: () => createLocalDataResolver,
|
|
@@ -95,16 +104,26 @@ __export(index_exports, {
|
|
|
95
104
|
cron: () => cron,
|
|
96
105
|
crud: () => crud,
|
|
97
106
|
defineBlueprint: () => defineBlueprint,
|
|
107
|
+
defineImperativeBlueprint: () => blueprint,
|
|
108
|
+
defineMiddleware: () => defineMiddleware,
|
|
98
109
|
defineModel: () => defineModel,
|
|
99
110
|
defineModule: () => defineModule,
|
|
111
|
+
defineRoles: () => defineRoles,
|
|
100
112
|
defineWorkspace: () => defineWorkspace,
|
|
113
|
+
delay: () => delay,
|
|
101
114
|
deriveInstanceKey: () => deriveInstanceKey,
|
|
102
115
|
deriveInstanceKeySync: () => deriveInstanceKeySync,
|
|
103
116
|
describeModel: () => describeModel,
|
|
104
117
|
deviceAction: () => deviceAction,
|
|
105
118
|
dmn: () => dmn,
|
|
119
|
+
editableBy: () => editableBy,
|
|
120
|
+
editableIn: () => editableIn,
|
|
121
|
+
emit: () => emit,
|
|
106
122
|
escalation: () => escalation,
|
|
123
|
+
every: () => every,
|
|
107
124
|
expr: () => expr,
|
|
125
|
+
extend: () => extend,
|
|
126
|
+
extendMiddleware: () => extendMiddleware,
|
|
108
127
|
field: () => field,
|
|
109
128
|
fieldContains: () => fieldContains,
|
|
110
129
|
fieldEquals: () => fieldEquals,
|
|
@@ -119,12 +138,21 @@ __export(index_exports, {
|
|
|
119
138
|
getInstalledModule: () => getInstalledModule,
|
|
120
139
|
getInstalledModules: () => getInstalledModules,
|
|
121
140
|
graphql: () => graphql,
|
|
141
|
+
guard: () => guard,
|
|
122
142
|
hasAnyRole: () => hasAnyRole,
|
|
123
143
|
hasRole: () => hasRole,
|
|
144
|
+
imperativeCron: () => cron2,
|
|
145
|
+
imperativeLog: () => log,
|
|
146
|
+
imperativeNotify: () => notify2,
|
|
147
|
+
imperativeRequireRole: () => requireRole2,
|
|
124
148
|
inState: () => inState,
|
|
125
149
|
inputEquals: () => inputEquals,
|
|
126
150
|
inputRequired: () => inputRequired,
|
|
151
|
+
instance: () => instance,
|
|
127
152
|
isActor: () => isActor,
|
|
153
|
+
isActorConfig: () => isActorConfig,
|
|
154
|
+
isBuiltInConstraint: () => isBuiltInConstraint,
|
|
155
|
+
isConstraintDeclaration: () => isConstraintDeclaration,
|
|
128
156
|
isCreator: () => isCreator,
|
|
129
157
|
isOwner: () => isOwner,
|
|
130
158
|
isPlayerDebug: () => isPlayerDebug,
|
|
@@ -134,19 +162,28 @@ __export(index_exports, {
|
|
|
134
162
|
loadExperienceWorkflow: () => loadExperienceWorkflow,
|
|
135
163
|
logEvent: () => logEvent,
|
|
136
164
|
model: () => model,
|
|
165
|
+
named: () => named,
|
|
137
166
|
normalizeDefinition: () => normalizeDefinition,
|
|
138
|
-
not: () =>
|
|
167
|
+
not: () => not,
|
|
139
168
|
notInState: () => notInState,
|
|
140
169
|
notify: () => notify,
|
|
141
|
-
|
|
170
|
+
on: () => on,
|
|
171
|
+
or: () => or,
|
|
172
|
+
orchestration: () => orchestration,
|
|
173
|
+
patch: () => patch,
|
|
142
174
|
pipe: () => pipe,
|
|
143
175
|
playerLog: () => playerLog,
|
|
144
176
|
prefetchData: () => prefetchData,
|
|
145
177
|
refHasAnyRole: () => refHasAnyRole,
|
|
146
178
|
refHasRole: () => refHasRole,
|
|
147
179
|
requireAuth: () => requireAuth,
|
|
180
|
+
requireField: () => requireField,
|
|
148
181
|
requireRole: () => requireRole,
|
|
182
|
+
resolveOrchestration: () => resolveOrchestration,
|
|
183
|
+
restrict: () => restrict,
|
|
149
184
|
review: () => review,
|
|
185
|
+
runtime: () => runtime,
|
|
186
|
+
sendMessage: () => sendMessage,
|
|
150
187
|
serverAction: () => serverAction,
|
|
151
188
|
setAuthResolver: () => setAuthResolver,
|
|
152
189
|
setChannelTransport: () => setChannelTransport,
|
|
@@ -166,10 +203,12 @@ __export(index_exports, {
|
|
|
166
203
|
setServerStateResolver: () => setServerStateResolver,
|
|
167
204
|
setViewResolver: () => setViewResolver,
|
|
168
205
|
spawn: () => spawn,
|
|
206
|
+
spawnActor: () => spawnActor,
|
|
169
207
|
sql: () => sql,
|
|
170
208
|
state: () => state,
|
|
171
209
|
syncConfigDefaults: () => syncConfigDefaults,
|
|
172
210
|
testModel: () => testModel,
|
|
211
|
+
timeout: () => timeout,
|
|
173
212
|
transition: () => transition,
|
|
174
213
|
updateDefinitionConfig: () => updateDefinitionConfig,
|
|
175
214
|
useAuth: () => useAuth,
|
|
@@ -202,6 +241,7 @@ __export(index_exports, {
|
|
|
202
241
|
usePlayer: () => usePlayer,
|
|
203
242
|
usePlayerContext: () => usePlayerContext,
|
|
204
243
|
usePlayerContextSafe: () => usePlayerContextSafe,
|
|
244
|
+
usePresence: () => usePresence,
|
|
205
245
|
useQuery: () => useQuery,
|
|
206
246
|
useRealtimeQuery: () => useRealtimeQuery,
|
|
207
247
|
useRole: () => useRole,
|
|
@@ -214,1113 +254,37 @@ __export(index_exports, {
|
|
|
214
254
|
useToast: () => useToast,
|
|
215
255
|
useTransition: () => useTransition,
|
|
216
256
|
useView: () => useView,
|
|
257
|
+
useVisibility: () => useVisibility,
|
|
217
258
|
useWhileIn: () => useWhileIn,
|
|
218
259
|
useWorkflow: () => useWorkflow,
|
|
219
|
-
useWorkflowState: () =>
|
|
260
|
+
useWorkflowState: () => useState21,
|
|
261
|
+
userAction: () => userAction,
|
|
262
|
+
userChoice: () => userChoice,
|
|
263
|
+
validate: () => validate,
|
|
220
264
|
validateExperienceWorkflow: () => validateExperienceWorkflow,
|
|
221
265
|
validateModel: () => validateModel,
|
|
266
|
+
visibleTo: () => visibleTo,
|
|
222
267
|
when: () => when,
|
|
268
|
+
withAuditLog: () => withAuditLog,
|
|
223
269
|
withAuditTrail: () => withAuditTrail,
|
|
270
|
+
withAuth: () => withAuth,
|
|
271
|
+
withMetrics: () => withMetrics,
|
|
224
272
|
withOwnership: () => withOwnership,
|
|
225
273
|
withPagination: () => withPagination,
|
|
226
274
|
withRBAC: () => withRBAC,
|
|
275
|
+
withRateLimit: () => withRateLimit,
|
|
227
276
|
withSearch: () => withSearch,
|
|
228
277
|
withSlug: () => withSlug,
|
|
229
278
|
withSoftDelete: () => withSoftDelete,
|
|
230
279
|
withTags: () => withTags,
|
|
231
280
|
withTimestamps: () => withTimestamps,
|
|
281
|
+
withValidation: () => withValidation,
|
|
232
282
|
withVersioning: () => withVersioning
|
|
233
283
|
});
|
|
234
284
|
module.exports = __toCommonJS(index_exports);
|
|
235
285
|
|
|
236
|
-
// ../player-core/dist/index.mjs
|
|
237
|
-
var add = {
|
|
238
|
-
name: "add",
|
|
239
|
-
fn: (a, b) => Number(a) + Number(b),
|
|
240
|
-
arity: 2
|
|
241
|
-
};
|
|
242
|
-
var subtract = {
|
|
243
|
-
name: "subtract",
|
|
244
|
-
fn: (a, b) => Number(a) - Number(b),
|
|
245
|
-
arity: 2
|
|
246
|
-
};
|
|
247
|
-
var multiply = {
|
|
248
|
-
name: "multiply",
|
|
249
|
-
fn: (a, b) => Number(a) * Number(b),
|
|
250
|
-
arity: 2
|
|
251
|
-
};
|
|
252
|
-
var divide = {
|
|
253
|
-
name: "divide",
|
|
254
|
-
fn: (a, b) => {
|
|
255
|
-
const d = Number(b);
|
|
256
|
-
return d === 0 ? 0 : Number(a) / d;
|
|
257
|
-
},
|
|
258
|
-
arity: 2
|
|
259
|
-
};
|
|
260
|
-
var abs = {
|
|
261
|
-
name: "abs",
|
|
262
|
-
fn: (a) => Math.abs(Number(a)),
|
|
263
|
-
arity: 1
|
|
264
|
-
};
|
|
265
|
-
var round = {
|
|
266
|
-
name: "round",
|
|
267
|
-
fn: (a, decimals) => {
|
|
268
|
-
const d = decimals != null ? Number(decimals) : 0;
|
|
269
|
-
const factor = Math.pow(10, d);
|
|
270
|
-
return Math.round(Number(a) * factor) / factor;
|
|
271
|
-
},
|
|
272
|
-
arity: -1
|
|
273
|
-
};
|
|
274
|
-
var min = {
|
|
275
|
-
name: "min",
|
|
276
|
-
fn: (...args) => {
|
|
277
|
-
const nums = args.flat().map(Number).filter((n) => !isNaN(n));
|
|
278
|
-
return nums.length === 0 ? 0 : Math.min(...nums);
|
|
279
|
-
},
|
|
280
|
-
arity: -1
|
|
281
|
-
};
|
|
282
|
-
var max = {
|
|
283
|
-
name: "max",
|
|
284
|
-
fn: (...args) => {
|
|
285
|
-
const nums = args.flat().map(Number).filter((n) => !isNaN(n));
|
|
286
|
-
return nums.length === 0 ? 0 : Math.max(...nums);
|
|
287
|
-
},
|
|
288
|
-
arity: -1
|
|
289
|
-
};
|
|
290
|
-
var eq = {
|
|
291
|
-
name: "eq",
|
|
292
|
-
fn: (a, b) => a === b || String(a) === String(b),
|
|
293
|
-
arity: 2
|
|
294
|
-
};
|
|
295
|
-
var neq = {
|
|
296
|
-
name: "neq",
|
|
297
|
-
fn: (a, b) => a !== b && String(a) !== String(b),
|
|
298
|
-
arity: 2
|
|
299
|
-
};
|
|
300
|
-
var gt = {
|
|
301
|
-
name: "gt",
|
|
302
|
-
fn: (a, b) => Number(a) > Number(b),
|
|
303
|
-
arity: 2
|
|
304
|
-
};
|
|
305
|
-
var gte = {
|
|
306
|
-
name: "gte",
|
|
307
|
-
fn: (a, b) => Number(a) >= Number(b),
|
|
308
|
-
arity: 2
|
|
309
|
-
};
|
|
310
|
-
var lt = {
|
|
311
|
-
name: "lt",
|
|
312
|
-
fn: (a, b) => Number(a) < Number(b),
|
|
313
|
-
arity: 2
|
|
314
|
-
};
|
|
315
|
-
var lte = {
|
|
316
|
-
name: "lte",
|
|
317
|
-
fn: (a, b) => Number(a) <= Number(b),
|
|
318
|
-
arity: 2
|
|
319
|
-
};
|
|
320
|
-
var if_fn = {
|
|
321
|
-
name: "if",
|
|
322
|
-
fn: (cond, then, else_) => cond ? then : else_,
|
|
323
|
-
arity: 3
|
|
324
|
-
};
|
|
325
|
-
var and = {
|
|
326
|
-
name: "and",
|
|
327
|
-
fn: (...args) => args.every(Boolean),
|
|
328
|
-
arity: -1
|
|
329
|
-
};
|
|
330
|
-
var or = {
|
|
331
|
-
name: "or",
|
|
332
|
-
fn: (...args) => args.some(Boolean),
|
|
333
|
-
arity: -1
|
|
334
|
-
};
|
|
335
|
-
var not = {
|
|
336
|
-
name: "not",
|
|
337
|
-
fn: (a) => !a,
|
|
338
|
-
arity: 1
|
|
339
|
-
};
|
|
340
|
-
var coalesce = {
|
|
341
|
-
name: "coalesce",
|
|
342
|
-
fn: (...args) => {
|
|
343
|
-
for (const arg of args) {
|
|
344
|
-
if (arg != null) return arg;
|
|
345
|
-
}
|
|
346
|
-
return null;
|
|
347
|
-
},
|
|
348
|
-
arity: -1
|
|
349
|
-
};
|
|
350
|
-
var concat = {
|
|
351
|
-
name: "concat",
|
|
352
|
-
fn: (...args) => args.map(String).join(""),
|
|
353
|
-
arity: -1
|
|
354
|
-
};
|
|
355
|
-
var upper = {
|
|
356
|
-
name: "upper",
|
|
357
|
-
fn: (s) => String(s ?? "").toUpperCase(),
|
|
358
|
-
arity: 1
|
|
359
|
-
};
|
|
360
|
-
var lower = {
|
|
361
|
-
name: "lower",
|
|
362
|
-
fn: (s) => String(s ?? "").toLowerCase(),
|
|
363
|
-
arity: 1
|
|
364
|
-
};
|
|
365
|
-
var trim = {
|
|
366
|
-
name: "trim",
|
|
367
|
-
fn: (s) => String(s ?? "").trim(),
|
|
368
|
-
arity: 1
|
|
369
|
-
};
|
|
370
|
-
var format = {
|
|
371
|
-
name: "format",
|
|
372
|
-
fn: (template, ...args) => {
|
|
373
|
-
let result = String(template ?? "");
|
|
374
|
-
args.forEach((arg, i) => {
|
|
375
|
-
result = result.replace(`{${i}}`, String(arg ?? ""));
|
|
376
|
-
});
|
|
377
|
-
return result;
|
|
378
|
-
},
|
|
379
|
-
arity: -1
|
|
380
|
-
};
|
|
381
|
-
var length = {
|
|
382
|
-
name: "length",
|
|
383
|
-
fn: (v) => {
|
|
384
|
-
if (Array.isArray(v)) return v.length;
|
|
385
|
-
if (typeof v === "string") return v.length;
|
|
386
|
-
if (v && typeof v === "object") return Object.keys(v).length;
|
|
387
|
-
return 0;
|
|
388
|
-
},
|
|
389
|
-
arity: 1
|
|
390
|
-
};
|
|
391
|
-
var get = {
|
|
392
|
-
name: "get",
|
|
393
|
-
fn: (obj, path) => {
|
|
394
|
-
if (obj == null || typeof path !== "string") return void 0;
|
|
395
|
-
const parts = path.split(".");
|
|
396
|
-
let current = obj;
|
|
397
|
-
for (const part of parts) {
|
|
398
|
-
if (current == null || typeof current !== "object") return void 0;
|
|
399
|
-
current = current[part];
|
|
400
|
-
}
|
|
401
|
-
return current;
|
|
402
|
-
},
|
|
403
|
-
arity: 2
|
|
404
|
-
};
|
|
405
|
-
var includes = {
|
|
406
|
-
name: "includes",
|
|
407
|
-
fn: (collection, value) => {
|
|
408
|
-
if (Array.isArray(collection)) return collection.includes(value);
|
|
409
|
-
if (typeof collection === "string") return collection.includes(String(value));
|
|
410
|
-
return false;
|
|
411
|
-
},
|
|
412
|
-
arity: 2
|
|
413
|
-
};
|
|
414
|
-
var is_defined = {
|
|
415
|
-
name: "is_defined",
|
|
416
|
-
fn: (v) => v !== void 0 && v !== null,
|
|
417
|
-
arity: 1
|
|
418
|
-
};
|
|
419
|
-
var is_empty = {
|
|
420
|
-
name: "is_empty",
|
|
421
|
-
fn: (v) => {
|
|
422
|
-
if (v == null) return true;
|
|
423
|
-
if (typeof v === "string") return v.length === 0;
|
|
424
|
-
if (Array.isArray(v)) return v.length === 0;
|
|
425
|
-
if (typeof v === "object") return Object.keys(v).length === 0;
|
|
426
|
-
return false;
|
|
427
|
-
},
|
|
428
|
-
arity: 1
|
|
429
|
-
};
|
|
430
|
-
var is_null = {
|
|
431
|
-
name: "is_null",
|
|
432
|
-
fn: (v) => v === null || v === void 0,
|
|
433
|
-
arity: 1
|
|
434
|
-
};
|
|
435
|
-
var to_string = {
|
|
436
|
-
name: "to_string",
|
|
437
|
-
fn: (v) => {
|
|
438
|
-
if (v == null) return "";
|
|
439
|
-
if (typeof v === "object") return JSON.stringify(v);
|
|
440
|
-
return String(v);
|
|
441
|
-
},
|
|
442
|
-
arity: 1
|
|
443
|
-
};
|
|
444
|
-
var CORE_FUNCTIONS = [
|
|
445
|
-
// Math (8)
|
|
446
|
-
add,
|
|
447
|
-
subtract,
|
|
448
|
-
multiply,
|
|
449
|
-
divide,
|
|
450
|
-
abs,
|
|
451
|
-
round,
|
|
452
|
-
min,
|
|
453
|
-
max,
|
|
454
|
-
// Comparison (6)
|
|
455
|
-
eq,
|
|
456
|
-
neq,
|
|
457
|
-
gt,
|
|
458
|
-
gte,
|
|
459
|
-
lt,
|
|
460
|
-
lte,
|
|
461
|
-
// Logic (5)
|
|
462
|
-
if_fn,
|
|
463
|
-
and,
|
|
464
|
-
or,
|
|
465
|
-
not,
|
|
466
|
-
coalesce,
|
|
467
|
-
// String (6)
|
|
468
|
-
concat,
|
|
469
|
-
upper,
|
|
470
|
-
lower,
|
|
471
|
-
trim,
|
|
472
|
-
format,
|
|
473
|
-
length,
|
|
474
|
-
// Path (3)
|
|
475
|
-
get,
|
|
476
|
-
includes,
|
|
477
|
-
is_defined,
|
|
478
|
-
// Type (3)
|
|
479
|
-
is_empty,
|
|
480
|
-
is_null,
|
|
481
|
-
to_string
|
|
482
|
-
];
|
|
483
|
-
function buildFunctionMap(functions) {
|
|
484
|
-
const map = /* @__PURE__ */ new Map();
|
|
485
|
-
for (const fn of functions) {
|
|
486
|
-
map.set(fn.name, fn.fn);
|
|
487
|
-
}
|
|
488
|
-
return map;
|
|
489
|
-
}
|
|
490
|
-
var MAX_DEPTH = 50;
|
|
491
|
-
var Parser = class {
|
|
492
|
-
pos = 0;
|
|
493
|
-
depth = 0;
|
|
494
|
-
input;
|
|
495
|
-
constructor(input) {
|
|
496
|
-
this.input = input;
|
|
497
|
-
}
|
|
498
|
-
parse() {
|
|
499
|
-
this.skipWhitespace();
|
|
500
|
-
const node = this.parseExpression();
|
|
501
|
-
this.skipWhitespace();
|
|
502
|
-
if (this.pos < this.input.length) {
|
|
503
|
-
throw new Error(`Unexpected character at position ${this.pos}: '${this.input[this.pos]}'`);
|
|
504
|
-
}
|
|
505
|
-
return node;
|
|
506
|
-
}
|
|
507
|
-
guardDepth() {
|
|
508
|
-
if (++this.depth > MAX_DEPTH) {
|
|
509
|
-
throw new Error("Expression too deeply nested");
|
|
510
|
-
}
|
|
511
|
-
}
|
|
512
|
-
parseExpression() {
|
|
513
|
-
this.guardDepth();
|
|
514
|
-
try {
|
|
515
|
-
return this.parseTernary();
|
|
516
|
-
} finally {
|
|
517
|
-
this.depth--;
|
|
518
|
-
}
|
|
519
|
-
}
|
|
520
|
-
parseTernary() {
|
|
521
|
-
let node = this.parseLogicalOr();
|
|
522
|
-
this.skipWhitespace();
|
|
523
|
-
if (this.peek() === "?") {
|
|
524
|
-
this.advance();
|
|
525
|
-
const consequent = this.parseExpression();
|
|
526
|
-
this.skipWhitespace();
|
|
527
|
-
this.expect(":");
|
|
528
|
-
const alternate = this.parseExpression();
|
|
529
|
-
node = { type: "ternary", condition: node, consequent, alternate };
|
|
530
|
-
}
|
|
531
|
-
return node;
|
|
532
|
-
}
|
|
533
|
-
parseLogicalOr() {
|
|
534
|
-
let left = this.parseLogicalAnd();
|
|
535
|
-
this.skipWhitespace();
|
|
536
|
-
while (this.match("||")) {
|
|
537
|
-
const right = this.parseLogicalAnd();
|
|
538
|
-
left = { type: "binary", operator: "||", left, right };
|
|
539
|
-
this.skipWhitespace();
|
|
540
|
-
}
|
|
541
|
-
return left;
|
|
542
|
-
}
|
|
543
|
-
parseLogicalAnd() {
|
|
544
|
-
let left = this.parseEquality();
|
|
545
|
-
this.skipWhitespace();
|
|
546
|
-
while (this.match("&&")) {
|
|
547
|
-
const right = this.parseEquality();
|
|
548
|
-
left = { type: "binary", operator: "&&", left, right };
|
|
549
|
-
this.skipWhitespace();
|
|
550
|
-
}
|
|
551
|
-
return left;
|
|
552
|
-
}
|
|
553
|
-
parseEquality() {
|
|
554
|
-
let left = this.parseComparison();
|
|
555
|
-
this.skipWhitespace();
|
|
556
|
-
while (true) {
|
|
557
|
-
if (this.match("==")) {
|
|
558
|
-
const right = this.parseComparison();
|
|
559
|
-
left = { type: "binary", operator: "==", left, right };
|
|
560
|
-
} else if (this.match("!=")) {
|
|
561
|
-
const right = this.parseComparison();
|
|
562
|
-
left = { type: "binary", operator: "!=", left, right };
|
|
563
|
-
} else {
|
|
564
|
-
break;
|
|
565
|
-
}
|
|
566
|
-
this.skipWhitespace();
|
|
567
|
-
}
|
|
568
|
-
return left;
|
|
569
|
-
}
|
|
570
|
-
parseComparison() {
|
|
571
|
-
let left = this.parseUnary();
|
|
572
|
-
this.skipWhitespace();
|
|
573
|
-
while (true) {
|
|
574
|
-
if (this.match(">=")) {
|
|
575
|
-
const right = this.parseUnary();
|
|
576
|
-
left = { type: "binary", operator: ">=", left, right };
|
|
577
|
-
} else if (this.match("<=")) {
|
|
578
|
-
const right = this.parseUnary();
|
|
579
|
-
left = { type: "binary", operator: "<=", left, right };
|
|
580
|
-
} else if (this.peek() === ">" && !this.lookAhead(">=")) {
|
|
581
|
-
this.advance();
|
|
582
|
-
const right = this.parseUnary();
|
|
583
|
-
left = { type: "binary", operator: ">", left, right };
|
|
584
|
-
} else if (this.peek() === "<" && !this.lookAhead("<=")) {
|
|
585
|
-
this.advance();
|
|
586
|
-
const right = this.parseUnary();
|
|
587
|
-
left = { type: "binary", operator: "<", left, right };
|
|
588
|
-
} else {
|
|
589
|
-
break;
|
|
590
|
-
}
|
|
591
|
-
this.skipWhitespace();
|
|
592
|
-
}
|
|
593
|
-
return left;
|
|
594
|
-
}
|
|
595
|
-
parseUnary() {
|
|
596
|
-
this.skipWhitespace();
|
|
597
|
-
if (this.peek() === "!") {
|
|
598
|
-
this.advance();
|
|
599
|
-
const operand = this.parseUnary();
|
|
600
|
-
return { type: "unary", operator: "!", operand };
|
|
601
|
-
}
|
|
602
|
-
if (this.peek() === "-") {
|
|
603
|
-
const nextChar = this.input[this.pos + 1];
|
|
604
|
-
if (nextChar !== void 0 && (nextChar >= "0" && nextChar <= "9" || nextChar === ".")) {
|
|
605
|
-
return this.parseCallChain();
|
|
606
|
-
}
|
|
607
|
-
}
|
|
608
|
-
return this.parseCallChain();
|
|
609
|
-
}
|
|
610
|
-
parseCallChain() {
|
|
611
|
-
let node = this.parsePrimary();
|
|
612
|
-
while (true) {
|
|
613
|
-
this.skipWhitespace();
|
|
614
|
-
if (this.peek() === "(") {
|
|
615
|
-
this.advance();
|
|
616
|
-
const args = this.parseArgList();
|
|
617
|
-
this.expect(")");
|
|
618
|
-
if (node.type === "identifier") {
|
|
619
|
-
node = { type: "call", name: node.name, args };
|
|
620
|
-
} else if (node.type === "path") {
|
|
621
|
-
const name = node.segments.join(".");
|
|
622
|
-
node = { type: "call", name, args };
|
|
623
|
-
} else if (node.type === "member") {
|
|
624
|
-
node = { type: "method_call", object: node.object, method: node.property, args };
|
|
625
|
-
} else {
|
|
626
|
-
throw new Error("Cannot call non-function");
|
|
627
|
-
}
|
|
628
|
-
} else if (this.peek() === ".") {
|
|
629
|
-
this.advance();
|
|
630
|
-
const prop = this.parseIdentifierName();
|
|
631
|
-
node = { type: "member", object: node, property: prop };
|
|
632
|
-
} else {
|
|
633
|
-
break;
|
|
634
|
-
}
|
|
635
|
-
}
|
|
636
|
-
return node;
|
|
637
|
-
}
|
|
638
|
-
parsePrimary() {
|
|
639
|
-
this.skipWhitespace();
|
|
640
|
-
const ch = this.peek();
|
|
641
|
-
if (ch === "(") {
|
|
642
|
-
this.advance();
|
|
643
|
-
const expr2 = this.parseExpression();
|
|
644
|
-
this.skipWhitespace();
|
|
645
|
-
this.expect(")");
|
|
646
|
-
return expr2;
|
|
647
|
-
}
|
|
648
|
-
if (ch === "'" || ch === '"') {
|
|
649
|
-
return this.parseString();
|
|
650
|
-
}
|
|
651
|
-
if (ch === "-" || ch >= "0" && ch <= "9") {
|
|
652
|
-
return this.parseNumber();
|
|
653
|
-
}
|
|
654
|
-
if (this.isIdentStart(ch)) {
|
|
655
|
-
return this.parseIdentifierOrPath();
|
|
656
|
-
}
|
|
657
|
-
throw new Error(
|
|
658
|
-
`Unexpected character at position ${this.pos}: '${ch || "EOF"}'`
|
|
659
|
-
);
|
|
660
|
-
}
|
|
661
|
-
parseString() {
|
|
662
|
-
const quote = this.advance();
|
|
663
|
-
let value = "";
|
|
664
|
-
while (this.pos < this.input.length && this.peek() !== quote) {
|
|
665
|
-
if (this.peek() === "\\") {
|
|
666
|
-
this.advance();
|
|
667
|
-
const esc = this.advance();
|
|
668
|
-
if (esc === "n") value += "\n";
|
|
669
|
-
else if (esc === "t") value += " ";
|
|
670
|
-
else if (esc === "r") value += "\r";
|
|
671
|
-
else value += esc;
|
|
672
|
-
} else {
|
|
673
|
-
value += this.advance();
|
|
674
|
-
}
|
|
675
|
-
}
|
|
676
|
-
if (this.pos >= this.input.length) {
|
|
677
|
-
throw new Error("Unterminated string literal");
|
|
678
|
-
}
|
|
679
|
-
this.advance();
|
|
680
|
-
return { type: "string", value };
|
|
681
|
-
}
|
|
682
|
-
parseNumber() {
|
|
683
|
-
let numStr = "";
|
|
684
|
-
if (this.peek() === "-") {
|
|
685
|
-
numStr += this.advance();
|
|
686
|
-
}
|
|
687
|
-
while (this.pos < this.input.length && (this.input[this.pos] >= "0" && this.input[this.pos] <= "9")) {
|
|
688
|
-
numStr += this.advance();
|
|
689
|
-
}
|
|
690
|
-
if (this.peek() === "." && this.pos + 1 < this.input.length && this.input[this.pos + 1] >= "0" && this.input[this.pos + 1] <= "9") {
|
|
691
|
-
numStr += this.advance();
|
|
692
|
-
while (this.pos < this.input.length && (this.input[this.pos] >= "0" && this.input[this.pos] <= "9")) {
|
|
693
|
-
numStr += this.advance();
|
|
694
|
-
}
|
|
695
|
-
}
|
|
696
|
-
return { type: "number", value: Number(numStr) };
|
|
697
|
-
}
|
|
698
|
-
parseIdentifierOrPath() {
|
|
699
|
-
const name = this.parseIdentifierName();
|
|
700
|
-
if (name === "true") return { type: "boolean", value: true };
|
|
701
|
-
if (name === "false") return { type: "boolean", value: false };
|
|
702
|
-
if (name === "null") return { type: "null" };
|
|
703
|
-
if (name === "undefined") return { type: "null" };
|
|
704
|
-
return { type: "identifier", name };
|
|
705
|
-
}
|
|
706
|
-
parseIdentifierName() {
|
|
707
|
-
let name = "";
|
|
708
|
-
if (this.peek() === "$") name += this.advance();
|
|
709
|
-
while (this.pos < this.input.length && this.isIdentPart(this.input[this.pos])) {
|
|
710
|
-
name += this.advance();
|
|
711
|
-
}
|
|
712
|
-
if (!name) {
|
|
713
|
-
throw new Error(`Expected identifier at position ${this.pos}`);
|
|
714
|
-
}
|
|
715
|
-
return name;
|
|
716
|
-
}
|
|
717
|
-
parseArgList() {
|
|
718
|
-
this.skipWhitespace();
|
|
719
|
-
if (this.peek() === ")") return [];
|
|
720
|
-
const args = [];
|
|
721
|
-
args.push(this.parseExpression());
|
|
722
|
-
this.skipWhitespace();
|
|
723
|
-
while (this.peek() === ",") {
|
|
724
|
-
this.advance();
|
|
725
|
-
args.push(this.parseExpression());
|
|
726
|
-
this.skipWhitespace();
|
|
727
|
-
}
|
|
728
|
-
return args;
|
|
729
|
-
}
|
|
730
|
-
// Character utilities
|
|
731
|
-
peek() {
|
|
732
|
-
return this.input[this.pos] ?? "";
|
|
733
|
-
}
|
|
734
|
-
advance() {
|
|
735
|
-
return this.input[this.pos++] ?? "";
|
|
736
|
-
}
|
|
737
|
-
match(str) {
|
|
738
|
-
if (this.input.startsWith(str, this.pos)) {
|
|
739
|
-
this.pos += str.length;
|
|
740
|
-
return true;
|
|
741
|
-
}
|
|
742
|
-
return false;
|
|
743
|
-
}
|
|
744
|
-
lookAhead(str) {
|
|
745
|
-
return this.input.startsWith(str, this.pos);
|
|
746
|
-
}
|
|
747
|
-
expect(ch) {
|
|
748
|
-
this.skipWhitespace();
|
|
749
|
-
if (this.peek() !== ch) {
|
|
750
|
-
throw new Error(`Expected '${ch}' at position ${this.pos}, got '${this.peek() || "EOF"}'`);
|
|
751
|
-
}
|
|
752
|
-
this.advance();
|
|
753
|
-
}
|
|
754
|
-
skipWhitespace() {
|
|
755
|
-
while (this.pos < this.input.length && " \n\r".includes(this.input[this.pos])) {
|
|
756
|
-
this.pos++;
|
|
757
|
-
}
|
|
758
|
-
}
|
|
759
|
-
isIdentStart(ch) {
|
|
760
|
-
return ch >= "a" && ch <= "z" || ch >= "A" && ch <= "Z" || ch === "_" || ch === "$";
|
|
761
|
-
}
|
|
762
|
-
isIdentPart(ch) {
|
|
763
|
-
return this.isIdentStart(ch) || ch >= "0" && ch <= "9";
|
|
764
|
-
}
|
|
765
|
-
};
|
|
766
|
-
function evaluateAST(node, context, fnMap) {
|
|
767
|
-
switch (node.type) {
|
|
768
|
-
case "number":
|
|
769
|
-
return node.value;
|
|
770
|
-
case "string":
|
|
771
|
-
return node.value;
|
|
772
|
-
case "boolean":
|
|
773
|
-
return node.value;
|
|
774
|
-
case "null":
|
|
775
|
-
return null;
|
|
776
|
-
case "identifier":
|
|
777
|
-
return resolvePath(node.name, context);
|
|
778
|
-
case "path":
|
|
779
|
-
return resolvePath(node.segments.join("."), context);
|
|
780
|
-
case "member": {
|
|
781
|
-
const obj = evaluateAST(node.object, context, fnMap);
|
|
782
|
-
if (obj == null || typeof obj !== "object") return void 0;
|
|
783
|
-
return obj[node.property];
|
|
784
|
-
}
|
|
785
|
-
case "call": {
|
|
786
|
-
const fn = fnMap.get(node.name);
|
|
787
|
-
if (!fn) return void 0;
|
|
788
|
-
const args = node.args.map((a) => evaluateAST(a, context, fnMap));
|
|
789
|
-
return fn(...args);
|
|
790
|
-
}
|
|
791
|
-
case "method_call": {
|
|
792
|
-
const obj = evaluateAST(node.object, context, fnMap);
|
|
793
|
-
if (obj != null && typeof obj === "object") {
|
|
794
|
-
const method = obj[node.method];
|
|
795
|
-
if (typeof method === "function") {
|
|
796
|
-
const args = node.args.map((a) => evaluateAST(a, context, fnMap));
|
|
797
|
-
return method.apply(obj, args);
|
|
798
|
-
}
|
|
799
|
-
}
|
|
800
|
-
return void 0;
|
|
801
|
-
}
|
|
802
|
-
case "unary": {
|
|
803
|
-
const operand = evaluateAST(node.operand, context, fnMap);
|
|
804
|
-
return !operand;
|
|
805
|
-
}
|
|
806
|
-
case "binary": {
|
|
807
|
-
if (node.operator === "&&") {
|
|
808
|
-
const left2 = evaluateAST(node.left, context, fnMap);
|
|
809
|
-
if (!left2) return left2;
|
|
810
|
-
return evaluateAST(node.right, context, fnMap);
|
|
811
|
-
}
|
|
812
|
-
if (node.operator === "||") {
|
|
813
|
-
const left2 = evaluateAST(node.left, context, fnMap);
|
|
814
|
-
if (left2) return left2;
|
|
815
|
-
return evaluateAST(node.right, context, fnMap);
|
|
816
|
-
}
|
|
817
|
-
const left = evaluateAST(node.left, context, fnMap);
|
|
818
|
-
const right = evaluateAST(node.right, context, fnMap);
|
|
819
|
-
switch (node.operator) {
|
|
820
|
-
// eslint-disable-next-line eqeqeq
|
|
821
|
-
case "==":
|
|
822
|
-
return left == right;
|
|
823
|
-
// eslint-disable-next-line eqeqeq
|
|
824
|
-
case "!=":
|
|
825
|
-
return left != right;
|
|
826
|
-
case ">":
|
|
827
|
-
return Number(left) > Number(right);
|
|
828
|
-
case "<":
|
|
829
|
-
return Number(left) < Number(right);
|
|
830
|
-
case ">=":
|
|
831
|
-
return Number(left) >= Number(right);
|
|
832
|
-
case "<=":
|
|
833
|
-
return Number(left) <= Number(right);
|
|
834
|
-
default:
|
|
835
|
-
return void 0;
|
|
836
|
-
}
|
|
837
|
-
}
|
|
838
|
-
case "ternary": {
|
|
839
|
-
const condition = evaluateAST(node.condition, context, fnMap);
|
|
840
|
-
return condition ? evaluateAST(node.consequent, context, fnMap) : evaluateAST(node.alternate, context, fnMap);
|
|
841
|
-
}
|
|
842
|
-
}
|
|
843
|
-
}
|
|
844
|
-
var MAX_CACHE = 500;
|
|
845
|
-
var astCache = /* @__PURE__ */ new Map();
|
|
846
|
-
function evictIfNeeded() {
|
|
847
|
-
if (astCache.size > MAX_CACHE) {
|
|
848
|
-
const keys = Array.from(astCache.keys());
|
|
849
|
-
const evictCount = Math.floor(MAX_CACHE * 0.25);
|
|
850
|
-
for (let i = 0; i < evictCount; i++) {
|
|
851
|
-
astCache.delete(keys[i]);
|
|
852
|
-
}
|
|
853
|
-
}
|
|
854
|
-
}
|
|
855
|
-
function parseAndCache(expr2) {
|
|
856
|
-
const cached = astCache.get(expr2);
|
|
857
|
-
if (cached) return cached;
|
|
858
|
-
const parser = new Parser(expr2);
|
|
859
|
-
const ast = parser.parse();
|
|
860
|
-
astCache.set(expr2, ast);
|
|
861
|
-
evictIfNeeded();
|
|
862
|
-
return ast;
|
|
863
|
-
}
|
|
864
|
-
var TEMPLATE_RE = /\{\{(.+?)\}\}/g;
|
|
865
|
-
function resolvePath(path, context) {
|
|
866
|
-
const parts = path.split(".");
|
|
867
|
-
let current = context;
|
|
868
|
-
for (const part of parts) {
|
|
869
|
-
if (current == null || typeof current !== "object") return void 0;
|
|
870
|
-
current = current[part];
|
|
871
|
-
}
|
|
872
|
-
return current;
|
|
873
|
-
}
|
|
874
|
-
function evaluateExpression(expr2, context, fnMap) {
|
|
875
|
-
const trimmed = expr2.trim();
|
|
876
|
-
if (trimmed === "true") return true;
|
|
877
|
-
if (trimmed === "false") return false;
|
|
878
|
-
if (trimmed === "null") return null;
|
|
879
|
-
if (trimmed === "undefined") return void 0;
|
|
880
|
-
const num = Number(trimmed);
|
|
881
|
-
if (!isNaN(num) && trimmed !== "") return num;
|
|
882
|
-
if (trimmed.startsWith("'") && trimmed.endsWith("'") || trimmed.startsWith('"') && trimmed.endsWith('"')) {
|
|
883
|
-
return trimmed.slice(1, -1);
|
|
884
|
-
}
|
|
885
|
-
if (/^[a-zA-Z_$][\w$.]*$/.test(trimmed)) {
|
|
886
|
-
return resolvePath(trimmed, context);
|
|
887
|
-
}
|
|
888
|
-
const ast = parseAndCache(trimmed);
|
|
889
|
-
return evaluateAST(ast, context, fnMap);
|
|
890
|
-
}
|
|
891
|
-
var WEB_FAILURE_POLICIES = {
|
|
892
|
-
VIEW_BINDING: {
|
|
893
|
-
on_error: "return_fallback",
|
|
894
|
-
fallback_value: "",
|
|
895
|
-
log_level: "warn"
|
|
896
|
-
},
|
|
897
|
-
EVENT_REACTION: {
|
|
898
|
-
on_error: "log_and_skip",
|
|
899
|
-
fallback_value: void 0,
|
|
900
|
-
log_level: "error"
|
|
901
|
-
},
|
|
902
|
-
DURING_ACTION: {
|
|
903
|
-
on_error: "log_and_skip",
|
|
904
|
-
fallback_value: void 0,
|
|
905
|
-
log_level: "error"
|
|
906
|
-
},
|
|
907
|
-
CONDITIONAL_VISIBILITY: {
|
|
908
|
-
on_error: "return_fallback",
|
|
909
|
-
fallback_value: true,
|
|
910
|
-
// Show by default if condition fails
|
|
911
|
-
log_level: "warn"
|
|
912
|
-
}
|
|
913
|
-
};
|
|
914
|
-
function createEvaluator(config) {
|
|
915
|
-
const allFunctions = [...CORE_FUNCTIONS, ...config.functions];
|
|
916
|
-
const fnMap = buildFunctionMap(allFunctions);
|
|
917
|
-
const policy = config.failurePolicy;
|
|
918
|
-
function handleError(expr2, error) {
|
|
919
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
920
|
-
if (policy.log_level === "error") {
|
|
921
|
-
console.error(`[player-core] Expression error: "${expr2}" \u2014 ${message}`);
|
|
922
|
-
} else if (policy.log_level === "warn") {
|
|
923
|
-
console.warn(`[player-core] Expression error: "${expr2}" \u2014 ${message}`);
|
|
924
|
-
}
|
|
925
|
-
switch (policy.on_error) {
|
|
926
|
-
case "throw":
|
|
927
|
-
throw error;
|
|
928
|
-
case "return_fallback":
|
|
929
|
-
return { value: policy.fallback_value, status: "fallback", error: message };
|
|
930
|
-
case "log_and_skip":
|
|
931
|
-
default:
|
|
932
|
-
return { value: policy.fallback_value, status: "error", error: message };
|
|
933
|
-
}
|
|
934
|
-
}
|
|
935
|
-
return {
|
|
936
|
-
evaluate(expression, context) {
|
|
937
|
-
try {
|
|
938
|
-
const value = evaluateExpression(expression, context, fnMap);
|
|
939
|
-
return { value, status: "ok" };
|
|
940
|
-
} catch (error) {
|
|
941
|
-
return handleError(expression, error);
|
|
942
|
-
}
|
|
943
|
-
},
|
|
944
|
-
evaluateTemplate(template, context) {
|
|
945
|
-
try {
|
|
946
|
-
if (!template.includes("{{")) {
|
|
947
|
-
return { value: template, status: "ok" };
|
|
948
|
-
}
|
|
949
|
-
const result = template.replace(TEMPLATE_RE, (_match, expr2) => {
|
|
950
|
-
const value = evaluateExpression(expr2, context, fnMap);
|
|
951
|
-
return value != null ? String(value) : "";
|
|
952
|
-
});
|
|
953
|
-
return { value: result, status: "ok" };
|
|
954
|
-
} catch (error) {
|
|
955
|
-
return handleError(template, error);
|
|
956
|
-
}
|
|
957
|
-
},
|
|
958
|
-
validate(expression) {
|
|
959
|
-
const errors = [];
|
|
960
|
-
try {
|
|
961
|
-
parseAndCache(expression);
|
|
962
|
-
} catch (e) {
|
|
963
|
-
errors.push(e instanceof Error ? e.message : String(e));
|
|
964
|
-
}
|
|
965
|
-
return { valid: errors.length === 0, errors };
|
|
966
|
-
}
|
|
967
|
-
};
|
|
968
|
-
}
|
|
969
|
-
var MAX_AUTO_CHAIN = 10;
|
|
970
|
-
var StateMachine = class {
|
|
971
|
-
evaluator;
|
|
972
|
-
actionHandlers;
|
|
973
|
-
listeners = /* @__PURE__ */ new Set();
|
|
974
|
-
instance;
|
|
975
|
-
constructor(definition, initialData = {}, config) {
|
|
976
|
-
this.evaluator = config.evaluator;
|
|
977
|
-
this.actionHandlers = config.actionHandlers ?? /* @__PURE__ */ new Map();
|
|
978
|
-
const startState = definition.states.find((s) => s.type === "START");
|
|
979
|
-
if (!startState) {
|
|
980
|
-
throw new Error(`No START state found in definition ${definition.slug}`);
|
|
981
|
-
}
|
|
982
|
-
this.instance = {
|
|
983
|
-
definition,
|
|
984
|
-
current_state: startState.name,
|
|
985
|
-
state_data: { ...initialData },
|
|
986
|
-
memory: {},
|
|
987
|
-
status: "ACTIVE"
|
|
988
|
-
};
|
|
989
|
-
}
|
|
990
|
-
/** Get the current instance snapshot (immutable copy) */
|
|
991
|
-
getSnapshot() {
|
|
992
|
-
return { ...this.instance, state_data: { ...this.instance.state_data }, memory: { ...this.instance.memory } };
|
|
993
|
-
}
|
|
994
|
-
/** Get current state name */
|
|
995
|
-
get currentState() {
|
|
996
|
-
return this.instance.current_state;
|
|
997
|
-
}
|
|
998
|
-
/** Get current state_data */
|
|
999
|
-
get stateData() {
|
|
1000
|
-
return this.instance.state_data;
|
|
1001
|
-
}
|
|
1002
|
-
/** Get current status */
|
|
1003
|
-
get status() {
|
|
1004
|
-
return this.instance.status;
|
|
1005
|
-
}
|
|
1006
|
-
/** Subscribe to state machine events */
|
|
1007
|
-
on(listener) {
|
|
1008
|
-
this.listeners.add(listener);
|
|
1009
|
-
return () => this.listeners.delete(listener);
|
|
1010
|
-
}
|
|
1011
|
-
/** Register an action handler */
|
|
1012
|
-
registerAction(type, handler) {
|
|
1013
|
-
this.actionHandlers.set(type, handler);
|
|
1014
|
-
}
|
|
1015
|
-
/** Execute a named transition */
|
|
1016
|
-
async transition(transitionName, data) {
|
|
1017
|
-
if (this.instance.status !== "ACTIVE") {
|
|
1018
|
-
return {
|
|
1019
|
-
success: false,
|
|
1020
|
-
from_state: this.instance.current_state,
|
|
1021
|
-
to_state: this.instance.current_state,
|
|
1022
|
-
actions_executed: [],
|
|
1023
|
-
error: `Cannot transition: instance status is ${this.instance.status}`
|
|
1024
|
-
};
|
|
1025
|
-
}
|
|
1026
|
-
const transition2 = this.instance.definition.transitions.find(
|
|
1027
|
-
(t) => t.name === transitionName && t.from.includes(this.instance.current_state)
|
|
1028
|
-
);
|
|
1029
|
-
if (!transition2) {
|
|
1030
|
-
return {
|
|
1031
|
-
success: false,
|
|
1032
|
-
from_state: this.instance.current_state,
|
|
1033
|
-
to_state: this.instance.current_state,
|
|
1034
|
-
actions_executed: [],
|
|
1035
|
-
error: `Transition "${transitionName}" not valid from state "${this.instance.current_state}"`
|
|
1036
|
-
};
|
|
1037
|
-
}
|
|
1038
|
-
if (data) {
|
|
1039
|
-
this.instance.state_data = { ...this.instance.state_data, ...data };
|
|
1040
|
-
}
|
|
1041
|
-
if (transition2.conditions && transition2.conditions.length > 0) {
|
|
1042
|
-
const ctx = this.buildContext();
|
|
1043
|
-
for (const condition of transition2.conditions) {
|
|
1044
|
-
const result2 = this.evaluator.evaluate(condition, ctx);
|
|
1045
|
-
if (!result2.value) {
|
|
1046
|
-
return {
|
|
1047
|
-
success: false,
|
|
1048
|
-
from_state: this.instance.current_state,
|
|
1049
|
-
to_state: this.instance.current_state,
|
|
1050
|
-
actions_executed: [],
|
|
1051
|
-
error: `Transition condition not met: ${condition}`
|
|
1052
|
-
};
|
|
1053
|
-
}
|
|
1054
|
-
}
|
|
1055
|
-
}
|
|
1056
|
-
const result = await this.executeTransition(transition2);
|
|
1057
|
-
if (result.success) {
|
|
1058
|
-
await this.drainAutoTransitions();
|
|
1059
|
-
}
|
|
1060
|
-
return result;
|
|
1061
|
-
}
|
|
1062
|
-
/** Update state_data directly (for on_event set_field actions) */
|
|
1063
|
-
setField(field2, value) {
|
|
1064
|
-
this.instance.state_data = { ...this.instance.state_data, [field2]: value };
|
|
1065
|
-
}
|
|
1066
|
-
/** Update memory */
|
|
1067
|
-
setMemory(key, value) {
|
|
1068
|
-
this.instance.memory = { ...this.instance.memory, [key]: value };
|
|
1069
|
-
}
|
|
1070
|
-
/** Get available transitions from the current state */
|
|
1071
|
-
getAvailableTransitions() {
|
|
1072
|
-
return this.instance.definition.transitions.filter(
|
|
1073
|
-
(t) => t.from.includes(this.instance.current_state) && !t.auto
|
|
1074
|
-
);
|
|
1075
|
-
}
|
|
1076
|
-
/** Get the current state definition */
|
|
1077
|
-
getCurrentStateDefinition() {
|
|
1078
|
-
return this.instance.definition.states.find((s) => s.name === this.instance.current_state);
|
|
1079
|
-
}
|
|
1080
|
-
// ===========================================================================
|
|
1081
|
-
// Private implementation
|
|
1082
|
-
// ===========================================================================
|
|
1083
|
-
async executeTransition(transition2) {
|
|
1084
|
-
const fromState = this.instance.current_state;
|
|
1085
|
-
const allActionsExecuted = [];
|
|
1086
|
-
const fromStateDef = this.getCurrentStateDefinition();
|
|
1087
|
-
if (fromStateDef?.on_exit) {
|
|
1088
|
-
await this.executeActions(fromStateDef.on_exit, allActionsExecuted);
|
|
1089
|
-
}
|
|
1090
|
-
this.emit({
|
|
1091
|
-
type: "state_exit",
|
|
1092
|
-
instance_id: this.instance.definition.id,
|
|
1093
|
-
from_state: fromState
|
|
1094
|
-
});
|
|
1095
|
-
if (transition2.actions) {
|
|
1096
|
-
await this.executeActions(transition2.actions, allActionsExecuted);
|
|
1097
|
-
}
|
|
1098
|
-
this.instance.current_state = transition2.to;
|
|
1099
|
-
const toStateDef = this.instance.definition.states.find((s) => s.name === transition2.to);
|
|
1100
|
-
if (toStateDef?.type === "END") {
|
|
1101
|
-
this.instance.status = "COMPLETED";
|
|
1102
|
-
} else if (toStateDef?.type === "CANCELLED") {
|
|
1103
|
-
this.instance.status = "CANCELLED";
|
|
1104
|
-
}
|
|
1105
|
-
this.emit({
|
|
1106
|
-
type: "state_enter",
|
|
1107
|
-
instance_id: this.instance.definition.id,
|
|
1108
|
-
to_state: transition2.to
|
|
1109
|
-
});
|
|
1110
|
-
if (toStateDef?.on_enter) {
|
|
1111
|
-
await this.executeActions(toStateDef.on_enter, allActionsExecuted);
|
|
1112
|
-
}
|
|
1113
|
-
this.emit({
|
|
1114
|
-
type: "transition",
|
|
1115
|
-
instance_id: this.instance.definition.id,
|
|
1116
|
-
from_state: fromState,
|
|
1117
|
-
to_state: transition2.to
|
|
1118
|
-
});
|
|
1119
|
-
return {
|
|
1120
|
-
success: true,
|
|
1121
|
-
from_state: fromState,
|
|
1122
|
-
to_state: transition2.to,
|
|
1123
|
-
actions_executed: allActionsExecuted
|
|
1124
|
-
};
|
|
1125
|
-
}
|
|
1126
|
-
async drainAutoTransitions() {
|
|
1127
|
-
for (let depth = 0; depth < MAX_AUTO_CHAIN; depth++) {
|
|
1128
|
-
if (this.instance.status !== "ACTIVE") break;
|
|
1129
|
-
const autoTransition = this.findMatchingAutoTransition();
|
|
1130
|
-
if (!autoTransition) break;
|
|
1131
|
-
const result = await this.executeTransition(autoTransition);
|
|
1132
|
-
if (!result.success) break;
|
|
1133
|
-
}
|
|
1134
|
-
}
|
|
1135
|
-
findMatchingAutoTransition() {
|
|
1136
|
-
const candidates = this.instance.definition.transitions.filter(
|
|
1137
|
-
(t) => t.auto && t.from.includes(this.instance.current_state)
|
|
1138
|
-
);
|
|
1139
|
-
const ctx = this.buildContext();
|
|
1140
|
-
for (const candidate of candidates) {
|
|
1141
|
-
if (!candidate.conditions || candidate.conditions.length === 0) {
|
|
1142
|
-
return candidate;
|
|
1143
|
-
}
|
|
1144
|
-
const allMet = candidate.conditions.every((condition) => {
|
|
1145
|
-
const result = this.evaluator.evaluate(condition, ctx);
|
|
1146
|
-
return result.value === true;
|
|
1147
|
-
});
|
|
1148
|
-
if (allMet) return candidate;
|
|
1149
|
-
}
|
|
1150
|
-
return null;
|
|
1151
|
-
}
|
|
1152
|
-
async executeActions(actions, collector) {
|
|
1153
|
-
const ctx = this.buildContext();
|
|
1154
|
-
for (const action2 of actions) {
|
|
1155
|
-
if (action2.condition) {
|
|
1156
|
-
const condResult = this.evaluator.evaluate(action2.condition, ctx);
|
|
1157
|
-
if (!condResult.value) continue;
|
|
1158
|
-
}
|
|
1159
|
-
const handler = this.actionHandlers.get(action2.type);
|
|
1160
|
-
if (handler) {
|
|
1161
|
-
try {
|
|
1162
|
-
await handler(action2, ctx);
|
|
1163
|
-
collector.push(action2);
|
|
1164
|
-
this.emit({
|
|
1165
|
-
type: "action_executed",
|
|
1166
|
-
instance_id: this.instance.definition.id,
|
|
1167
|
-
action: action2
|
|
1168
|
-
});
|
|
1169
|
-
} catch (error) {
|
|
1170
|
-
this.emit({
|
|
1171
|
-
type: "error",
|
|
1172
|
-
instance_id: this.instance.definition.id,
|
|
1173
|
-
action: action2,
|
|
1174
|
-
error: error instanceof Error ? error.message : String(error)
|
|
1175
|
-
});
|
|
1176
|
-
}
|
|
1177
|
-
}
|
|
1178
|
-
}
|
|
1179
|
-
}
|
|
1180
|
-
buildContext() {
|
|
1181
|
-
return {
|
|
1182
|
-
state_data: this.instance.state_data,
|
|
1183
|
-
memory: this.instance.memory,
|
|
1184
|
-
current_state: this.instance.current_state,
|
|
1185
|
-
status: this.instance.status,
|
|
1186
|
-
// Spread state_data for direct field access (e.g., "title" instead of "state_data.title")
|
|
1187
|
-
...this.instance.state_data
|
|
1188
|
-
};
|
|
1189
|
-
}
|
|
1190
|
-
emit(event) {
|
|
1191
|
-
for (const listener of this.listeners) {
|
|
1192
|
-
try {
|
|
1193
|
-
listener(event);
|
|
1194
|
-
} catch {
|
|
1195
|
-
}
|
|
1196
|
-
}
|
|
1197
|
-
}
|
|
1198
|
-
};
|
|
1199
|
-
var patternCache = /* @__PURE__ */ new Map();
|
|
1200
|
-
var MAX_CACHE2 = 200;
|
|
1201
|
-
function compilePattern(pattern) {
|
|
1202
|
-
const cached = patternCache.get(pattern);
|
|
1203
|
-
if (cached) return cached;
|
|
1204
|
-
const escaped = pattern.replace(/[.+?^${}()|[\]\\]/g, "\\$&").replace(/\*\*/g, "<<DOUBLESTAR>>").replace(/\*/g, "[^:.]+").replace(/<<DOUBLESTAR>>/g, ".*");
|
|
1205
|
-
const regex = new RegExp(`^${escaped}$`);
|
|
1206
|
-
if (patternCache.size >= MAX_CACHE2) {
|
|
1207
|
-
const firstKey = patternCache.keys().next().value;
|
|
1208
|
-
if (firstKey) patternCache.delete(firstKey);
|
|
1209
|
-
}
|
|
1210
|
-
patternCache.set(pattern, regex);
|
|
1211
|
-
return regex;
|
|
1212
|
-
}
|
|
1213
|
-
function matchTopic(pattern, topic) {
|
|
1214
|
-
return pattern.test(topic);
|
|
1215
|
-
}
|
|
1216
|
-
var EventBus = class {
|
|
1217
|
-
subscriptions = [];
|
|
1218
|
-
/**
|
|
1219
|
-
* Subscribe to events matching a glob pattern.
|
|
1220
|
-
* Returns an unsubscribe function.
|
|
1221
|
-
*/
|
|
1222
|
-
subscribe(pattern, handler) {
|
|
1223
|
-
const regex = compilePattern(pattern);
|
|
1224
|
-
const subscription = { pattern, regex, handler };
|
|
1225
|
-
this.subscriptions.push(subscription);
|
|
1226
|
-
return () => {
|
|
1227
|
-
const idx = this.subscriptions.indexOf(subscription);
|
|
1228
|
-
if (idx !== -1) this.subscriptions.splice(idx, 1);
|
|
1229
|
-
};
|
|
1230
|
-
}
|
|
1231
|
-
/**
|
|
1232
|
-
* Publish an event. All matching subscriptions fire (async).
|
|
1233
|
-
* Errors in handlers are caught and logged, never propagated.
|
|
1234
|
-
*/
|
|
1235
|
-
async publish(topic, payload = {}) {
|
|
1236
|
-
const event = { topic, payload };
|
|
1237
|
-
for (const sub of this.subscriptions) {
|
|
1238
|
-
if (matchTopic(sub.regex, topic)) {
|
|
1239
|
-
try {
|
|
1240
|
-
await sub.handler(event);
|
|
1241
|
-
} catch (error) {
|
|
1242
|
-
console.warn(
|
|
1243
|
-
`[player-core] Event handler error for pattern "${sub.pattern}" on topic "${topic}":`,
|
|
1244
|
-
error
|
|
1245
|
-
);
|
|
1246
|
-
}
|
|
1247
|
-
}
|
|
1248
|
-
}
|
|
1249
|
-
}
|
|
1250
|
-
/**
|
|
1251
|
-
* Publish synchronously (fire-and-forget).
|
|
1252
|
-
* Useful when you don't need to await handler completion.
|
|
1253
|
-
*/
|
|
1254
|
-
emit(topic, payload = {}) {
|
|
1255
|
-
void this.publish(topic, payload);
|
|
1256
|
-
}
|
|
1257
|
-
/** Get count of active subscriptions */
|
|
1258
|
-
get size() {
|
|
1259
|
-
return this.subscriptions.length;
|
|
1260
|
-
}
|
|
1261
|
-
/** Remove all subscriptions */
|
|
1262
|
-
clear() {
|
|
1263
|
-
this.subscriptions.length = 0;
|
|
1264
|
-
}
|
|
1265
|
-
};
|
|
1266
|
-
var ActionDispatcher = class {
|
|
1267
|
-
handlers = /* @__PURE__ */ new Map();
|
|
1268
|
-
/** Register a handler for an action type */
|
|
1269
|
-
register(type, handler) {
|
|
1270
|
-
this.handlers.set(type, handler);
|
|
1271
|
-
}
|
|
1272
|
-
/** Unregister a handler */
|
|
1273
|
-
unregister(type) {
|
|
1274
|
-
this.handlers.delete(type);
|
|
1275
|
-
}
|
|
1276
|
-
/** Check if a handler is registered for the given type */
|
|
1277
|
-
has(type) {
|
|
1278
|
-
return this.handlers.has(type);
|
|
1279
|
-
}
|
|
1280
|
-
/**
|
|
1281
|
-
* Execute a list of actions sequentially.
|
|
1282
|
-
* Each action's condition is evaluated first (if present).
|
|
1283
|
-
* Missing handlers are skipped with a warning.
|
|
1284
|
-
*/
|
|
1285
|
-
async execute(actions, context, evaluator) {
|
|
1286
|
-
const results = [];
|
|
1287
|
-
for (const action2 of actions) {
|
|
1288
|
-
if (action2.condition && evaluator) {
|
|
1289
|
-
const condResult = evaluator.evaluate(action2.condition, context);
|
|
1290
|
-
if (!condResult.value) continue;
|
|
1291
|
-
}
|
|
1292
|
-
const handler = this.handlers.get(action2.type);
|
|
1293
|
-
if (!handler) {
|
|
1294
|
-
console.warn(`[player-core] No handler registered for action type "${action2.type}" \u2014 unsupported action`);
|
|
1295
|
-
results.push({ type: action2.type, success: false, error: `unsupported action: "${action2.type}"` });
|
|
1296
|
-
continue;
|
|
1297
|
-
}
|
|
1298
|
-
try {
|
|
1299
|
-
await handler(action2.config, context);
|
|
1300
|
-
results.push({ type: action2.type, success: true });
|
|
1301
|
-
} catch (error) {
|
|
1302
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
1303
|
-
console.warn(`[player-core] Action "${action2.type}" failed: ${message}`);
|
|
1304
|
-
results.push({ type: action2.type, success: false, error: message });
|
|
1305
|
-
}
|
|
1306
|
-
}
|
|
1307
|
-
return results;
|
|
1308
|
-
}
|
|
1309
|
-
/** Get count of registered handlers */
|
|
1310
|
-
get size() {
|
|
1311
|
-
return this.handlers.size;
|
|
1312
|
-
}
|
|
1313
|
-
/** Get all registered action type names */
|
|
1314
|
-
getRegisteredTypes() {
|
|
1315
|
-
return Array.from(this.handlers.keys());
|
|
1316
|
-
}
|
|
1317
|
-
/** Remove all handlers */
|
|
1318
|
-
clear() {
|
|
1319
|
-
this.handlers.clear();
|
|
1320
|
-
}
|
|
1321
|
-
};
|
|
1322
|
-
|
|
1323
286
|
// src/core/WorkflowRuntime.ts
|
|
287
|
+
var import_player_core = require("@mmapp/player-core");
|
|
1324
288
|
var WorkflowRuntime = class {
|
|
1325
289
|
sm;
|
|
1326
290
|
eventBus;
|
|
@@ -1328,9 +292,9 @@ var WorkflowRuntime = class {
|
|
|
1328
292
|
evaluator;
|
|
1329
293
|
listeners = /* @__PURE__ */ new Set();
|
|
1330
294
|
constructor(config) {
|
|
1331
|
-
this.evaluator = createEvaluator({
|
|
295
|
+
this.evaluator = (0, import_player_core.createEvaluator)({
|
|
1332
296
|
functions: [],
|
|
1333
|
-
failurePolicy: WEB_FAILURE_POLICIES.EVENT_REACTION
|
|
297
|
+
failurePolicy: import_player_core.WEB_FAILURE_POLICIES.EVENT_REACTION
|
|
1334
298
|
});
|
|
1335
299
|
const actionHandlers = /* @__PURE__ */ new Map();
|
|
1336
300
|
if (config.actionHandlers) {
|
|
@@ -1352,14 +316,14 @@ var WorkflowRuntime = class {
|
|
|
1352
316
|
smRef.setMemory(action2.config.key, action2.config.value);
|
|
1353
317
|
}
|
|
1354
318
|
});
|
|
1355
|
-
this.sm = new StateMachine(
|
|
319
|
+
this.sm = new import_player_core.StateMachine(
|
|
1356
320
|
config.definition,
|
|
1357
321
|
config.initialData ?? {},
|
|
1358
322
|
{ evaluator: this.evaluator, actionHandlers }
|
|
1359
323
|
);
|
|
1360
324
|
smRef = this.sm;
|
|
1361
|
-
this.eventBus = new EventBus();
|
|
1362
|
-
this.dispatcher = new ActionDispatcher();
|
|
325
|
+
this.eventBus = new import_player_core.EventBus();
|
|
326
|
+
this.dispatcher = new import_player_core.ActionDispatcher();
|
|
1363
327
|
this.dispatcher.register("set_field", (cfg) => {
|
|
1364
328
|
if (smRef && typeof cfg.field === "string") {
|
|
1365
329
|
smRef.setField(cfg.field, cfg.value);
|
|
@@ -1419,24 +383,24 @@ var import_react2 = require("react");
|
|
|
1419
383
|
var import_react = require("react");
|
|
1420
384
|
var RuntimeContext = (0, import_react.createContext)(null);
|
|
1421
385
|
function useRuntimeContext() {
|
|
1422
|
-
const
|
|
1423
|
-
if (!
|
|
386
|
+
const runtime2 = (0, import_react.useContext)(RuntimeContext);
|
|
387
|
+
if (!runtime2) {
|
|
1424
388
|
throw new Error(
|
|
1425
389
|
"useRuntimeContext must be used within a WorkflowProvider or RuntimeContext.Provider"
|
|
1426
390
|
);
|
|
1427
391
|
}
|
|
1428
|
-
return
|
|
392
|
+
return runtime2;
|
|
1429
393
|
}
|
|
1430
394
|
|
|
1431
395
|
// src/hooks/useOnEnter.ts
|
|
1432
396
|
function useOnEnter(stateName, effect) {
|
|
1433
|
-
const
|
|
397
|
+
const runtime2 = useRuntimeContext();
|
|
1434
398
|
const effectRef = (0, import_react2.useRef)(effect);
|
|
1435
399
|
effectRef.current = effect;
|
|
1436
400
|
const cleanupRef = (0, import_react2.useRef)(null);
|
|
1437
401
|
const states = Array.isArray(stateName) ? stateName : [stateName];
|
|
1438
402
|
(0, import_react2.useEffect)(() => {
|
|
1439
|
-
if (states.includes(
|
|
403
|
+
if (states.includes(runtime2.sm.currentState)) {
|
|
1440
404
|
const result = effectRef.current();
|
|
1441
405
|
if (result instanceof Promise) {
|
|
1442
406
|
result.then((cleanup) => {
|
|
@@ -1446,7 +410,7 @@ function useOnEnter(stateName, effect) {
|
|
|
1446
410
|
cleanupRef.current = result;
|
|
1447
411
|
}
|
|
1448
412
|
}
|
|
1449
|
-
const unsub =
|
|
413
|
+
const unsub = runtime2.sm.on((event) => {
|
|
1450
414
|
if (event.type === "state_enter" && event.to_state && states.includes(event.to_state)) {
|
|
1451
415
|
cleanupRef.current?.();
|
|
1452
416
|
const result = effectRef.current();
|
|
@@ -1467,34 +431,34 @@ function useOnEnter(stateName, effect) {
|
|
|
1467
431
|
unsub();
|
|
1468
432
|
cleanupRef.current?.();
|
|
1469
433
|
};
|
|
1470
|
-
}, [
|
|
434
|
+
}, [runtime2, ...states]);
|
|
1471
435
|
}
|
|
1472
436
|
|
|
1473
437
|
// src/hooks/useOnExit.ts
|
|
1474
438
|
var import_react3 = require("react");
|
|
1475
439
|
function useOnExit(stateName, effect) {
|
|
1476
|
-
const
|
|
440
|
+
const runtime2 = useRuntimeContext();
|
|
1477
441
|
const effectRef = (0, import_react3.useRef)(effect);
|
|
1478
442
|
effectRef.current = effect;
|
|
1479
443
|
const states = Array.isArray(stateName) ? stateName : [stateName];
|
|
1480
444
|
(0, import_react3.useEffect)(() => {
|
|
1481
|
-
const unsub =
|
|
445
|
+
const unsub = runtime2.sm.on((event) => {
|
|
1482
446
|
if (event.type === "state_exit" && event.from_state && states.includes(event.from_state)) {
|
|
1483
447
|
effectRef.current();
|
|
1484
448
|
}
|
|
1485
449
|
});
|
|
1486
450
|
return unsub;
|
|
1487
|
-
}, [
|
|
451
|
+
}, [runtime2, ...states]);
|
|
1488
452
|
}
|
|
1489
453
|
|
|
1490
454
|
// src/hooks/useOnTransition.ts
|
|
1491
455
|
var import_react4 = require("react");
|
|
1492
456
|
function useOnTransition(effect) {
|
|
1493
|
-
const
|
|
457
|
+
const runtime2 = useRuntimeContext();
|
|
1494
458
|
const effectRef = (0, import_react4.useRef)(effect);
|
|
1495
459
|
effectRef.current = effect;
|
|
1496
460
|
(0, import_react4.useEffect)(() => {
|
|
1497
|
-
const unsub =
|
|
461
|
+
const unsub = runtime2.sm.on((event) => {
|
|
1498
462
|
if (event.type === "transition") {
|
|
1499
463
|
effectRef.current({
|
|
1500
464
|
from: event.from_state,
|
|
@@ -1503,33 +467,33 @@ function useOnTransition(effect) {
|
|
|
1503
467
|
}
|
|
1504
468
|
});
|
|
1505
469
|
return unsub;
|
|
1506
|
-
}, [
|
|
470
|
+
}, [runtime2]);
|
|
1507
471
|
}
|
|
1508
472
|
|
|
1509
473
|
// src/hooks/useOnEvent.ts
|
|
1510
474
|
var import_react5 = require("react");
|
|
1511
475
|
function useOnEvent(pattern, handler, options) {
|
|
1512
|
-
const
|
|
476
|
+
const runtime2 = useRuntimeContext();
|
|
1513
477
|
const handlerRef = (0, import_react5.useRef)(handler);
|
|
1514
478
|
handlerRef.current = handler;
|
|
1515
479
|
(0, import_react5.useEffect)(() => {
|
|
1516
|
-
const unsub =
|
|
1517
|
-
if (options?.while &&
|
|
480
|
+
const unsub = runtime2.eventBus.subscribe(pattern, (event) => {
|
|
481
|
+
if (options?.while && runtime2.sm.currentState !== options.while) return;
|
|
1518
482
|
handlerRef.current(event);
|
|
1519
483
|
});
|
|
1520
484
|
return unsub;
|
|
1521
|
-
}, [
|
|
485
|
+
}, [runtime2, pattern, options?.while]);
|
|
1522
486
|
}
|
|
1523
487
|
|
|
1524
488
|
// src/hooks/useOnChange.ts
|
|
1525
489
|
var import_react6 = require("react");
|
|
1526
490
|
function useOnChange(field2, handler) {
|
|
1527
|
-
const
|
|
491
|
+
const runtime2 = useRuntimeContext();
|
|
1528
492
|
const handlerRef = (0, import_react6.useRef)(handler);
|
|
1529
493
|
handlerRef.current = handler;
|
|
1530
|
-
const prevRef = (0, import_react6.useRef)(
|
|
494
|
+
const prevRef = (0, import_react6.useRef)(runtime2.sm.stateData[field2]);
|
|
1531
495
|
(0, import_react6.useEffect)(() => {
|
|
1532
|
-
const unsub =
|
|
496
|
+
const unsub = runtime2.subscribe((snap) => {
|
|
1533
497
|
const newVal = snap.stateData[field2];
|
|
1534
498
|
if (newVal !== prevRef.current) {
|
|
1535
499
|
handlerRef.current(newVal, prevRef.current);
|
|
@@ -1537,13 +501,13 @@ function useOnChange(field2, handler) {
|
|
|
1537
501
|
}
|
|
1538
502
|
});
|
|
1539
503
|
return unsub;
|
|
1540
|
-
}, [
|
|
504
|
+
}, [runtime2, field2]);
|
|
1541
505
|
}
|
|
1542
506
|
|
|
1543
507
|
// src/hooks/useWhileIn.ts
|
|
1544
508
|
var import_react7 = require("react");
|
|
1545
509
|
function useWhileIn(stateName, intervalMs, effect) {
|
|
1546
|
-
const
|
|
510
|
+
const runtime2 = useRuntimeContext();
|
|
1547
511
|
const effectRef = (0, import_react7.useRef)(effect);
|
|
1548
512
|
effectRef.current = effect;
|
|
1549
513
|
(0, import_react7.useEffect)(() => {
|
|
@@ -1558,8 +522,8 @@ function useWhileIn(stateName, intervalMs, effect) {
|
|
|
1558
522
|
timer = null;
|
|
1559
523
|
}
|
|
1560
524
|
}
|
|
1561
|
-
if (
|
|
1562
|
-
const unsub =
|
|
525
|
+
if (runtime2.sm.currentState === stateName) startInterval();
|
|
526
|
+
const unsub = runtime2.sm.on((event) => {
|
|
1563
527
|
if (event.type === "state_enter" && event.to_state === stateName) startInterval();
|
|
1564
528
|
if (event.type === "state_exit" && event.from_state === stateName) stopInterval();
|
|
1565
529
|
});
|
|
@@ -1567,13 +531,13 @@ function useWhileIn(stateName, intervalMs, effect) {
|
|
|
1567
531
|
unsub();
|
|
1568
532
|
stopInterval();
|
|
1569
533
|
};
|
|
1570
|
-
}, [
|
|
534
|
+
}, [runtime2, stateName, intervalMs]);
|
|
1571
535
|
}
|
|
1572
536
|
|
|
1573
537
|
// src/hooks/useDuringAction.ts
|
|
1574
538
|
var import_react8 = require("react");
|
|
1575
539
|
function useDuringAction(config) {
|
|
1576
|
-
const
|
|
540
|
+
const runtime2 = useRuntimeContext();
|
|
1577
541
|
const actionRef = (0, import_react8.useRef)(config.action);
|
|
1578
542
|
actionRef.current = config.action;
|
|
1579
543
|
const states = Array.isArray(config.state) ? config.state : [config.state];
|
|
@@ -1611,10 +575,10 @@ function useDuringAction(config) {
|
|
|
1611
575
|
timer = null;
|
|
1612
576
|
}
|
|
1613
577
|
}
|
|
1614
|
-
if (states.includes(
|
|
578
|
+
if (states.includes(runtime2.sm.currentState)) {
|
|
1615
579
|
startAction();
|
|
1616
580
|
}
|
|
1617
|
-
const unsub =
|
|
581
|
+
const unsub = runtime2.sm.on((event) => {
|
|
1618
582
|
if (event.type === "state_enter" && event.to_state && states.includes(event.to_state)) {
|
|
1619
583
|
startAction();
|
|
1620
584
|
}
|
|
@@ -1626,7 +590,7 @@ function useDuringAction(config) {
|
|
|
1626
590
|
unsub();
|
|
1627
591
|
stopAction();
|
|
1628
592
|
};
|
|
1629
|
-
}, [
|
|
593
|
+
}, [runtime2, intervalMs, immediate, enabled, ...states]);
|
|
1630
594
|
}
|
|
1631
595
|
|
|
1632
596
|
// src/hooks/useQuery.ts
|
|
@@ -2119,29 +1083,29 @@ function useServerState(instanceId, options = {}) {
|
|
|
2119
1083
|
// src/hooks/useWorkflow.ts
|
|
2120
1084
|
var import_react15 = require("react");
|
|
2121
1085
|
function useWorkflow(definition, options) {
|
|
2122
|
-
const
|
|
1086
|
+
const runtime2 = (0, import_react15.useMemo)(() => new WorkflowRuntime({
|
|
2123
1087
|
definition,
|
|
2124
1088
|
initialData: options?.initialData,
|
|
2125
1089
|
actionHandlers: options?.actionHandlers
|
|
2126
1090
|
}), [definition.id]);
|
|
2127
|
-
const [snapshot, setSnapshot] = (0, import_react15.useState)(() =>
|
|
1091
|
+
const [snapshot, setSnapshot] = (0, import_react15.useState)(() => runtime2.getSnapshot());
|
|
2128
1092
|
(0, import_react15.useEffect)(() => {
|
|
2129
|
-
const unsub =
|
|
1093
|
+
const unsub = runtime2.subscribe(setSnapshot);
|
|
2130
1094
|
return unsub;
|
|
2131
|
-
}, [
|
|
1095
|
+
}, [runtime2]);
|
|
2132
1096
|
const transition2 = (0, import_react15.useCallback)(async (name, data) => {
|
|
2133
|
-
const result = await
|
|
1097
|
+
const result = await runtime2.transition(name, data);
|
|
2134
1098
|
options?.onTransition?.(result);
|
|
2135
1099
|
return result;
|
|
2136
|
-
}, [
|
|
1100
|
+
}, [runtime2, options?.onTransition]);
|
|
2137
1101
|
const handle = {
|
|
2138
1102
|
slug: definition.slug,
|
|
2139
1103
|
...snapshot,
|
|
2140
1104
|
transition: transition2,
|
|
2141
|
-
setField:
|
|
2142
|
-
setMemory:
|
|
2143
|
-
publishEvent:
|
|
2144
|
-
runtime
|
|
1105
|
+
setField: runtime2.setField.bind(runtime2),
|
|
1106
|
+
setMemory: runtime2.setMemory.bind(runtime2),
|
|
1107
|
+
publishEvent: runtime2.publishEvent.bind(runtime2),
|
|
1108
|
+
runtime: runtime2
|
|
2145
1109
|
};
|
|
2146
1110
|
return handle;
|
|
2147
1111
|
}
|
|
@@ -2149,17 +1113,17 @@ function useWorkflow(definition, options) {
|
|
|
2149
1113
|
// src/hooks/useTransition.ts
|
|
2150
1114
|
var import_react16 = require("react");
|
|
2151
1115
|
function useTransition(transitionName, _config) {
|
|
2152
|
-
const
|
|
1116
|
+
const runtime2 = useRuntimeContext();
|
|
2153
1117
|
const [pending, setPending] = (0, import_react16.useState)(false);
|
|
2154
|
-
const available =
|
|
1118
|
+
const available = runtime2.sm.getAvailableTransitions().some((t) => t.name === transitionName);
|
|
2155
1119
|
const fire = (0, import_react16.useCallback)(async (data) => {
|
|
2156
1120
|
setPending(true);
|
|
2157
1121
|
try {
|
|
2158
|
-
return await
|
|
1122
|
+
return await runtime2.transition(transitionName, data);
|
|
2159
1123
|
} finally {
|
|
2160
1124
|
setPending(false);
|
|
2161
1125
|
}
|
|
2162
|
-
}, [
|
|
1126
|
+
}, [runtime2, transitionName]);
|
|
2163
1127
|
const handle = { fire, available, pending };
|
|
2164
1128
|
return handle;
|
|
2165
1129
|
}
|
|
@@ -2171,12 +1135,12 @@ function setRoleHierarchy(hierarchy) {
|
|
|
2171
1135
|
_globalHierarchy = hierarchy;
|
|
2172
1136
|
}
|
|
2173
1137
|
function useRole(roleName, options = {}) {
|
|
2174
|
-
const
|
|
1138
|
+
const runtime2 = useRuntimeContext();
|
|
2175
1139
|
const hierarchy = options.hierarchy ?? _globalHierarchy ?? [];
|
|
2176
1140
|
const inheritPermissions = options.inheritPermissions ?? true;
|
|
2177
1141
|
const result = (0, import_react17.useMemo)(() => {
|
|
2178
|
-
const snapshot =
|
|
2179
|
-
const definition =
|
|
1142
|
+
const snapshot = runtime2.getSnapshot();
|
|
1143
|
+
const definition = runtime2.config?.definition;
|
|
2180
1144
|
const userRoles = snapshot.stateData?._userRoles ?? snapshot.stateData?.user_roles ?? [];
|
|
2181
1145
|
let hasRole2 = userRoles.includes(roleName);
|
|
2182
1146
|
if (!hasRole2 && hierarchy.length > 0) {
|
|
@@ -2224,7 +1188,7 @@ function useRole(roleName, options = {}) {
|
|
|
2224
1188
|
}
|
|
2225
1189
|
}
|
|
2226
1190
|
return { hasRole: hasRole2, permissions, roles: userRoles, highestRole };
|
|
2227
|
-
}, [
|
|
1191
|
+
}, [runtime2, roleName, hierarchy, inheritPermissions]);
|
|
2228
1192
|
const isAbove = (0, import_react17.useCallback)(
|
|
2229
1193
|
(role) => {
|
|
2230
1194
|
if (hierarchy.length === 0) return false;
|
|
@@ -2275,21 +1239,21 @@ function useRole(roleName, options = {}) {
|
|
|
2275
1239
|
// src/hooks/useParams.ts
|
|
2276
1240
|
var import_react18 = require("react");
|
|
2277
1241
|
function useParams() {
|
|
2278
|
-
const
|
|
1242
|
+
const runtime2 = useRuntimeContext();
|
|
2279
1243
|
return (0, import_react18.useMemo)(() => {
|
|
2280
|
-
const snapshot =
|
|
1244
|
+
const snapshot = runtime2.getSnapshot();
|
|
2281
1245
|
const params = snapshot.stateData?._params ?? snapshot.memory?._callParams ?? {};
|
|
2282
1246
|
return params;
|
|
2283
|
-
}, [
|
|
1247
|
+
}, [runtime2]);
|
|
2284
1248
|
}
|
|
2285
1249
|
|
|
2286
1250
|
// src/hooks/usePackage.ts
|
|
2287
1251
|
var import_react19 = require("react");
|
|
2288
1252
|
function usePackage(packageSlug) {
|
|
2289
|
-
const
|
|
1253
|
+
const runtime2 = useRuntimeContext();
|
|
2290
1254
|
return (0, import_react19.useMemo)(() => {
|
|
2291
|
-
const snapshot =
|
|
2292
|
-
const definition =
|
|
1255
|
+
const snapshot = runtime2.getSnapshot();
|
|
1256
|
+
const definition = runtime2.config?.definition;
|
|
2293
1257
|
const childDefs = definition?.child_definitions ?? [];
|
|
2294
1258
|
const metadata = definition?.metadata ?? {};
|
|
2295
1259
|
if (definition?.slug === packageSlug && definition?.category === "blueprint") {
|
|
@@ -2352,7 +1316,7 @@ function usePackage(packageSlug) {
|
|
|
2352
1316
|
isResolved: false,
|
|
2353
1317
|
dependencySlugs: []
|
|
2354
1318
|
};
|
|
2355
|
-
}, [
|
|
1319
|
+
}, [runtime2, packageSlug]);
|
|
2356
1320
|
}
|
|
2357
1321
|
|
|
2358
1322
|
// src/hooks/useRouter.ts
|
|
@@ -2478,16 +1442,16 @@ function useRouter(options = {}) {
|
|
|
2478
1442
|
};
|
|
2479
1443
|
setIsNavigating(true);
|
|
2480
1444
|
try {
|
|
2481
|
-
for (const
|
|
2482
|
-
const allowed = await
|
|
1445
|
+
for (const guard2 of guardsRef.current) {
|
|
1446
|
+
const allowed = await guard2(to, location);
|
|
2483
1447
|
if (!allowed) {
|
|
2484
1448
|
onRejectRef.current?.(to);
|
|
2485
1449
|
return false;
|
|
2486
1450
|
}
|
|
2487
1451
|
}
|
|
2488
1452
|
if (found?.route?.guards) {
|
|
2489
|
-
for (const
|
|
2490
|
-
const allowed = await
|
|
1453
|
+
for (const guard2 of found.route.guards) {
|
|
1454
|
+
const allowed = await guard2(to, location);
|
|
2491
1455
|
if (!allowed) {
|
|
2492
1456
|
if (found.route.redirectOnFail) {
|
|
2493
1457
|
const fullRedirect = basePathRef.current + found.route.redirectOnFail;
|
|
@@ -2913,7 +1877,7 @@ function useGeolocation(options = {}) {
|
|
|
2913
1877
|
const {
|
|
2914
1878
|
enableHighAccuracy = false,
|
|
2915
1879
|
maximumAge = 0,
|
|
2916
|
-
timeout = 1e4,
|
|
1880
|
+
timeout: timeout2 = 1e4,
|
|
2917
1881
|
watch = false,
|
|
2918
1882
|
enabled = true
|
|
2919
1883
|
} = options;
|
|
@@ -2924,8 +1888,8 @@ function useGeolocation(options = {}) {
|
|
|
2924
1888
|
const watchIdRef = (0, import_react24.useRef)(null);
|
|
2925
1889
|
const supported = typeof navigator !== "undefined" && "geolocation" in navigator;
|
|
2926
1890
|
const positionOptions = (0, import_react24.useMemo)(
|
|
2927
|
-
() => ({ enableHighAccuracy, maximumAge, timeout }),
|
|
2928
|
-
[enableHighAccuracy, maximumAge,
|
|
1891
|
+
() => ({ enableHighAccuracy, maximumAge, timeout: timeout2 }),
|
|
1892
|
+
[enableHighAccuracy, maximumAge, timeout2]
|
|
2929
1893
|
);
|
|
2930
1894
|
const handleSuccess = (0, import_react24.useCallback)((pos) => {
|
|
2931
1895
|
setPosition({
|
|
@@ -3285,7 +2249,7 @@ var import_react27 = require("react");
|
|
|
3285
2249
|
function useForm(config) {
|
|
3286
2250
|
const {
|
|
3287
2251
|
initialValues,
|
|
3288
|
-
validate,
|
|
2252
|
+
validate: validate2,
|
|
3289
2253
|
fieldValidators,
|
|
3290
2254
|
onSubmit,
|
|
3291
2255
|
onError,
|
|
@@ -3298,8 +2262,8 @@ function useForm(config) {
|
|
|
3298
2262
|
const [isSubmitting, setIsSubmitting] = (0, import_react27.useState)(false);
|
|
3299
2263
|
const [submitCount, setSubmitCount] = (0, import_react27.useState)(0);
|
|
3300
2264
|
const initialRef = (0, import_react27.useRef)(initialValues);
|
|
3301
|
-
const validateRef = (0, import_react27.useRef)(
|
|
3302
|
-
validateRef.current =
|
|
2265
|
+
const validateRef = (0, import_react27.useRef)(validate2);
|
|
2266
|
+
validateRef.current = validate2;
|
|
3303
2267
|
const fieldValidatorsRef = (0, import_react27.useRef)(fieldValidators);
|
|
3304
2268
|
fieldValidatorsRef.current = fieldValidators;
|
|
3305
2269
|
const onSubmitRef = (0, import_react27.useRef)(onSubmit);
|
|
@@ -3516,7 +2480,7 @@ function useNotification() {
|
|
|
3516
2480
|
setPermission(result);
|
|
3517
2481
|
return result;
|
|
3518
2482
|
}, [supported]);
|
|
3519
|
-
const
|
|
2483
|
+
const notify3 = (0, import_react28.useCallback)(
|
|
3520
2484
|
(title, options = {}) => {
|
|
3521
2485
|
if (!supported || permission !== "granted") return null;
|
|
3522
2486
|
const {
|
|
@@ -3549,8 +2513,8 @@ function useNotification() {
|
|
|
3549
2513
|
[supported, permission]
|
|
3550
2514
|
);
|
|
3551
2515
|
return (0, import_react28.useMemo)(
|
|
3552
|
-
() => ({ permission, supported, requestPermission, notify:
|
|
3553
|
-
[permission, supported, requestPermission,
|
|
2516
|
+
() => ({ permission, supported, requestPermission, notify: notify3 }),
|
|
2517
|
+
[permission, supported, requestPermission, notify3]
|
|
3554
2518
|
);
|
|
3555
2519
|
}
|
|
3556
2520
|
|
|
@@ -3567,12 +2531,12 @@ function notifyListeners() {
|
|
|
3567
2531
|
}
|
|
3568
2532
|
function addToast(config) {
|
|
3569
2533
|
const id = `toast-${++_nextId}`;
|
|
3570
|
-
const
|
|
2534
|
+
const instance2 = {
|
|
3571
2535
|
...config,
|
|
3572
2536
|
id,
|
|
3573
2537
|
createdAt: Date.now()
|
|
3574
2538
|
};
|
|
3575
|
-
_toasts = [..._toasts,
|
|
2539
|
+
_toasts = [..._toasts, instance2];
|
|
3576
2540
|
const duration = config.duration ?? 5e3;
|
|
3577
2541
|
if (duration > 0) {
|
|
3578
2542
|
const timer = setTimeout(() => {
|
|
@@ -3623,8 +2587,191 @@ function useToast() {
|
|
|
3623
2587
|
);
|
|
3624
2588
|
}
|
|
3625
2589
|
|
|
3626
|
-
// src/hooks/
|
|
2590
|
+
// src/hooks/useVisibility.ts
|
|
3627
2591
|
var import_react30 = require("react");
|
|
2592
|
+
function useVisibility(model2, role, playerType) {
|
|
2593
|
+
return (0, import_react30.useMemo)(() => {
|
|
2594
|
+
return computeVisibility(model2, role, playerType);
|
|
2595
|
+
}, [model2, role, playerType]);
|
|
2596
|
+
}
|
|
2597
|
+
function computeVisibility(model2, role, playerType) {
|
|
2598
|
+
const allFields = Object.keys(model2.fields || {});
|
|
2599
|
+
const allStates = Object.keys(model2.states || {});
|
|
2600
|
+
const vis = model2.orchestration?.visibility;
|
|
2601
|
+
if (!vis) {
|
|
2602
|
+
return makeResult(allFields, allStates);
|
|
2603
|
+
}
|
|
2604
|
+
let roleFields;
|
|
2605
|
+
let roleStates;
|
|
2606
|
+
let playerFields;
|
|
2607
|
+
if (role && vis.roles && vis.roles[role]) {
|
|
2608
|
+
const rv = vis.roles[role];
|
|
2609
|
+
roleFields = rv.fields === "*" ? "*" : [...rv.fields];
|
|
2610
|
+
roleStates = rv.states === "*" ? "*" : rv.states ? [...rv.states] : "*";
|
|
2611
|
+
}
|
|
2612
|
+
if (playerType && vis.players && vis.players[playerType]) {
|
|
2613
|
+
const pv = vis.players[playerType];
|
|
2614
|
+
playerFields = pv.fields === "*" ? "*" : [...pv.fields];
|
|
2615
|
+
}
|
|
2616
|
+
if (roleFields === void 0 && playerFields === void 0) {
|
|
2617
|
+
return makeResult(allFields, allStates);
|
|
2618
|
+
}
|
|
2619
|
+
let resolvedFields;
|
|
2620
|
+
if (roleFields === "*" && playerFields === "*") {
|
|
2621
|
+
resolvedFields = allFields;
|
|
2622
|
+
} else if (roleFields === "*") {
|
|
2623
|
+
resolvedFields = playerFields === void 0 ? allFields : playerFields;
|
|
2624
|
+
} else if (playerFields === "*") {
|
|
2625
|
+
resolvedFields = roleFields === void 0 ? allFields : roleFields;
|
|
2626
|
+
} else if (roleFields !== void 0 && playerFields !== void 0) {
|
|
2627
|
+
const roleSet = new Set(roleFields);
|
|
2628
|
+
resolvedFields = playerFields.filter((f) => roleSet.has(f));
|
|
2629
|
+
} else {
|
|
2630
|
+
resolvedFields = roleFields || playerFields || allFields;
|
|
2631
|
+
}
|
|
2632
|
+
const resolvedStates = roleStates === "*" || roleStates === void 0 ? allStates : roleStates;
|
|
2633
|
+
return makeResult(resolvedFields, resolvedStates);
|
|
2634
|
+
}
|
|
2635
|
+
function makeResult(fields, states) {
|
|
2636
|
+
const fieldSet = new Set(fields);
|
|
2637
|
+
const stateSet = new Set(states);
|
|
2638
|
+
return {
|
|
2639
|
+
visibleFields: fields,
|
|
2640
|
+
visibleStates: states,
|
|
2641
|
+
canSeeField: (f) => fieldSet.has(f),
|
|
2642
|
+
canSeeState: (s) => stateSet.has(s)
|
|
2643
|
+
};
|
|
2644
|
+
}
|
|
2645
|
+
|
|
2646
|
+
// src/hooks/usePresence.ts
|
|
2647
|
+
var import_react31 = require("react");
|
|
2648
|
+
var PRESENCE_EVENTS = {
|
|
2649
|
+
JOIN: "presence:join",
|
|
2650
|
+
LEAVE: "presence:leave",
|
|
2651
|
+
HEARTBEAT: "presence:heartbeat",
|
|
2652
|
+
EDIT_START: "presence:edit_start",
|
|
2653
|
+
EDIT_STOP: "presence:edit_stop"
|
|
2654
|
+
};
|
|
2655
|
+
function usePresence(instanceId, options = {}) {
|
|
2656
|
+
const {
|
|
2657
|
+
userId = "anonymous",
|
|
2658
|
+
userName = "Anonymous",
|
|
2659
|
+
wsUrl,
|
|
2660
|
+
enabled = true,
|
|
2661
|
+
heartbeatInterval = 15e3,
|
|
2662
|
+
staleTimeout = 45e3
|
|
2663
|
+
} = options;
|
|
2664
|
+
const channelName = `presence:${instanceId}`;
|
|
2665
|
+
const { publish, subscribe, connected } = useChannel(channelName, {
|
|
2666
|
+
wsUrl,
|
|
2667
|
+
enabled
|
|
2668
|
+
});
|
|
2669
|
+
const [viewers, setViewers] = (0, import_react31.useState)([]);
|
|
2670
|
+
const [editors, setEditors] = (0, import_react31.useState)([]);
|
|
2671
|
+
const viewersRef = (0, import_react31.useRef)(/* @__PURE__ */ new Map());
|
|
2672
|
+
const editorsRef = (0, import_react31.useRef)(/* @__PURE__ */ new Map());
|
|
2673
|
+
(0, import_react31.useEffect)(() => {
|
|
2674
|
+
if (!connected || !enabled) return;
|
|
2675
|
+
publish(PRESENCE_EVENTS.JOIN, { id: userId, name: userName, connectedAt: Date.now() });
|
|
2676
|
+
const hb = setInterval(() => {
|
|
2677
|
+
publish(PRESENCE_EVENTS.HEARTBEAT, { id: userId, name: userName });
|
|
2678
|
+
}, heartbeatInterval);
|
|
2679
|
+
return () => {
|
|
2680
|
+
clearInterval(hb);
|
|
2681
|
+
publish(PRESENCE_EVENTS.LEAVE, { id: userId });
|
|
2682
|
+
};
|
|
2683
|
+
}, [connected, enabled, userId, userName, heartbeatInterval, publish]);
|
|
2684
|
+
(0, import_react31.useEffect)(() => {
|
|
2685
|
+
if (!enabled) return;
|
|
2686
|
+
const cleanup = setInterval(() => {
|
|
2687
|
+
const now = Date.now();
|
|
2688
|
+
const stale = [];
|
|
2689
|
+
for (const [id, v] of viewersRef.current) {
|
|
2690
|
+
if (now - v.connectedAt > staleTimeout) stale.push(id);
|
|
2691
|
+
}
|
|
2692
|
+
if (stale.length > 0) {
|
|
2693
|
+
for (const id of stale) {
|
|
2694
|
+
viewersRef.current.delete(id);
|
|
2695
|
+
editorsRef.current.delete(id);
|
|
2696
|
+
}
|
|
2697
|
+
setViewers(Array.from(viewersRef.current.values()));
|
|
2698
|
+
setEditors(Array.from(editorsRef.current.values()));
|
|
2699
|
+
}
|
|
2700
|
+
}, staleTimeout / 3);
|
|
2701
|
+
return () => clearInterval(cleanup);
|
|
2702
|
+
}, [enabled, staleTimeout]);
|
|
2703
|
+
(0, import_react31.useEffect)(() => {
|
|
2704
|
+
if (!enabled) return;
|
|
2705
|
+
const unsubs = [];
|
|
2706
|
+
unsubs.push(subscribe(PRESENCE_EVENTS.JOIN, (data) => {
|
|
2707
|
+
if (data.id === userId) return;
|
|
2708
|
+
viewersRef.current.set(data.id, {
|
|
2709
|
+
id: data.id,
|
|
2710
|
+
name: data.name || "Anonymous",
|
|
2711
|
+
connectedAt: data.connectedAt || Date.now()
|
|
2712
|
+
});
|
|
2713
|
+
setViewers(Array.from(viewersRef.current.values()));
|
|
2714
|
+
}));
|
|
2715
|
+
unsubs.push(subscribe(PRESENCE_EVENTS.LEAVE, (data) => {
|
|
2716
|
+
viewersRef.current.delete(data.id);
|
|
2717
|
+
editorsRef.current.delete(data.id);
|
|
2718
|
+
setViewers(Array.from(viewersRef.current.values()));
|
|
2719
|
+
setEditors(Array.from(editorsRef.current.values()));
|
|
2720
|
+
}));
|
|
2721
|
+
unsubs.push(subscribe(PRESENCE_EVENTS.HEARTBEAT, (data) => {
|
|
2722
|
+
if (data.id === userId) return;
|
|
2723
|
+
const existing = viewersRef.current.get(data.id);
|
|
2724
|
+
if (existing) {
|
|
2725
|
+
existing.connectedAt = Date.now();
|
|
2726
|
+
} else {
|
|
2727
|
+
viewersRef.current.set(data.id, {
|
|
2728
|
+
id: data.id,
|
|
2729
|
+
name: data.name || "Anonymous",
|
|
2730
|
+
connectedAt: Date.now()
|
|
2731
|
+
});
|
|
2732
|
+
setViewers(Array.from(viewersRef.current.values()));
|
|
2733
|
+
}
|
|
2734
|
+
}));
|
|
2735
|
+
unsubs.push(subscribe(PRESENCE_EVENTS.EDIT_START, (data) => {
|
|
2736
|
+
if (data.id === userId) return;
|
|
2737
|
+
editorsRef.current.set(data.id, {
|
|
2738
|
+
id: data.id,
|
|
2739
|
+
name: data.name || "Anonymous",
|
|
2740
|
+
field: data.field,
|
|
2741
|
+
startedAt: Date.now()
|
|
2742
|
+
});
|
|
2743
|
+
setEditors(Array.from(editorsRef.current.values()));
|
|
2744
|
+
}));
|
|
2745
|
+
unsubs.push(subscribe(PRESENCE_EVENTS.EDIT_STOP, (data) => {
|
|
2746
|
+
editorsRef.current.delete(data.id);
|
|
2747
|
+
setEditors(Array.from(editorsRef.current.values()));
|
|
2748
|
+
}));
|
|
2749
|
+
return () => unsubs.forEach((fn) => fn());
|
|
2750
|
+
}, [enabled, userId, subscribe]);
|
|
2751
|
+
const startEditing = (0, import_react31.useCallback)((field2) => {
|
|
2752
|
+
publish(PRESENCE_EVENTS.EDIT_START, { id: userId, name: userName, field: field2 });
|
|
2753
|
+
}, [publish, userId, userName]);
|
|
2754
|
+
const stopEditing = (0, import_react31.useCallback)((_field) => {
|
|
2755
|
+
publish(PRESENCE_EVENTS.EDIT_STOP, { id: userId });
|
|
2756
|
+
}, [publish, userId]);
|
|
2757
|
+
const isEditing = (0, import_react31.useCallback)((field2) => {
|
|
2758
|
+
for (const editor of editorsRef.current.values()) {
|
|
2759
|
+
if (editor.field === field2 && editor.id !== userId) return true;
|
|
2760
|
+
}
|
|
2761
|
+
return false;
|
|
2762
|
+
}, [userId]);
|
|
2763
|
+
return {
|
|
2764
|
+
viewers,
|
|
2765
|
+
editors,
|
|
2766
|
+
viewerCount: viewers.length,
|
|
2767
|
+
isEditing,
|
|
2768
|
+
startEditing,
|
|
2769
|
+
stopEditing
|
|
2770
|
+
};
|
|
2771
|
+
}
|
|
2772
|
+
|
|
2773
|
+
// src/hooks/useMiddleware.ts
|
|
2774
|
+
var import_react32 = require("react");
|
|
3628
2775
|
function requireAuth(loginPath = "/login") {
|
|
3629
2776
|
return (ctx) => {
|
|
3630
2777
|
if (!ctx.token) {
|
|
@@ -3696,24 +2843,24 @@ function useMiddleware(middlewares, options = {}) {
|
|
|
3696
2843
|
watchPathname = true,
|
|
3697
2844
|
onRedirect
|
|
3698
2845
|
} = options;
|
|
3699
|
-
const [ready, setReady] = (0,
|
|
3700
|
-
const [loading, setLoading] = (0,
|
|
3701
|
-
const [redirect, setRedirect] = (0,
|
|
3702
|
-
const [error, setError] = (0,
|
|
3703
|
-
const [data, setData] = (0,
|
|
3704
|
-
const [runKey, setRunKey] = (0,
|
|
3705
|
-
const middlewaresRef = (0,
|
|
2846
|
+
const [ready, setReady] = (0, import_react32.useState)(false);
|
|
2847
|
+
const [loading, setLoading] = (0, import_react32.useState)(true);
|
|
2848
|
+
const [redirect, setRedirect] = (0, import_react32.useState)(null);
|
|
2849
|
+
const [error, setError] = (0, import_react32.useState)(null);
|
|
2850
|
+
const [data, setData] = (0, import_react32.useState)({});
|
|
2851
|
+
const [runKey, setRunKey] = (0, import_react32.useState)(0);
|
|
2852
|
+
const middlewaresRef = (0, import_react32.useRef)(middlewares);
|
|
3706
2853
|
middlewaresRef.current = middlewares;
|
|
3707
|
-
const onRedirectRef = (0,
|
|
2854
|
+
const onRedirectRef = (0, import_react32.useRef)(onRedirect);
|
|
3708
2855
|
onRedirectRef.current = onRedirect;
|
|
3709
|
-
const [pathname, setPathname] = (0,
|
|
3710
|
-
(0,
|
|
2856
|
+
const [pathname, setPathname] = (0, import_react32.useState)(getPathname);
|
|
2857
|
+
(0, import_react32.useEffect)(() => {
|
|
3711
2858
|
if (!watchPathname) return;
|
|
3712
2859
|
const handler = () => setPathname(getPathname());
|
|
3713
2860
|
window.addEventListener("popstate", handler);
|
|
3714
2861
|
return () => window.removeEventListener("popstate", handler);
|
|
3715
2862
|
}, [watchPathname]);
|
|
3716
|
-
(0,
|
|
2863
|
+
(0, import_react32.useEffect)(() => {
|
|
3717
2864
|
if (!enabled) {
|
|
3718
2865
|
setReady(true);
|
|
3719
2866
|
setLoading(false);
|
|
@@ -3760,11 +2907,11 @@ function useMiddleware(middlewares, options = {}) {
|
|
|
3760
2907
|
cancelled = true;
|
|
3761
2908
|
};
|
|
3762
2909
|
}, [enabled, pathname, runKey]);
|
|
3763
|
-
const rerun = (0,
|
|
2910
|
+
const rerun = (0, import_react32.useMemo)(
|
|
3764
2911
|
() => () => setRunKey((k) => k + 1),
|
|
3765
2912
|
[]
|
|
3766
2913
|
);
|
|
3767
|
-
return (0,
|
|
2914
|
+
return (0, import_react32.useMemo)(
|
|
3768
2915
|
() => ({ ready, loading, redirect, error, data, rerun }),
|
|
3769
2916
|
[ready, loading, redirect, error, data, rerun]
|
|
3770
2917
|
);
|
|
@@ -3774,8 +2921,8 @@ function useMiddleware(middlewares, options = {}) {
|
|
|
3774
2921
|
var import_react_query = require("@tanstack/react-query");
|
|
3775
2922
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
3776
2923
|
var defaultQueryClient = new import_react_query.QueryClient();
|
|
3777
|
-
function WorkflowProvider({ runtime, queryClient, children }) {
|
|
3778
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_query.QueryClientProvider, { client: queryClient ?? defaultQueryClient, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RuntimeContext.Provider, { value:
|
|
2924
|
+
function WorkflowProvider({ runtime: runtime2, queryClient, children }) {
|
|
2925
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_query.QueryClientProvider, { client: queryClient ?? defaultQueryClient, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RuntimeContext.Provider, { value: runtime2, children }) });
|
|
3779
2926
|
}
|
|
3780
2927
|
|
|
3781
2928
|
// src/local/LocalEngine.ts
|
|
@@ -3836,8 +2983,8 @@ var LocalWorkflowEngine = class {
|
|
|
3836
2983
|
* Process all pending events from a transition result.
|
|
3837
2984
|
* Emits locally and returns the events for P2P broadcast.
|
|
3838
2985
|
*/
|
|
3839
|
-
processPendingEvents(
|
|
3840
|
-
const events =
|
|
2986
|
+
processPendingEvents(instance2) {
|
|
2987
|
+
const events = instance2._pendingEvents;
|
|
3841
2988
|
if (!events?.length) return [];
|
|
3842
2989
|
for (const evt of events) {
|
|
3843
2990
|
this.emitEvent(evt);
|
|
@@ -3880,18 +3027,18 @@ var LocalWorkflowEngine = class {
|
|
|
3880
3027
|
};
|
|
3881
3028
|
}
|
|
3882
3029
|
/** Check if a transition can fire from the instance's current state */
|
|
3883
|
-
canTransition(
|
|
3884
|
-
const def = this.definitions.get(
|
|
3030
|
+
canTransition(instance2, transitionName) {
|
|
3031
|
+
const def = this.definitions.get(instance2.definitionSlug);
|
|
3885
3032
|
if (!def) return false;
|
|
3886
3033
|
const transition2 = def.transitions.find((t) => t.name === transitionName);
|
|
3887
3034
|
if (!transition2) return false;
|
|
3888
|
-
return transition2.from.includes(
|
|
3035
|
+
return transition2.from.includes(instance2.currentState);
|
|
3889
3036
|
}
|
|
3890
3037
|
/** Get all transitions available from the instance's current state */
|
|
3891
|
-
getAvailableTransitions(
|
|
3892
|
-
const def = this.definitions.get(
|
|
3038
|
+
getAvailableTransitions(instance2) {
|
|
3039
|
+
const def = this.definitions.get(instance2.definitionSlug);
|
|
3893
3040
|
if (!def) return [];
|
|
3894
|
-
return def.transitions.filter((t) => t.from.includes(
|
|
3041
|
+
return def.transitions.filter((t) => t.from.includes(instance2.currentState)).map((t) => t.name);
|
|
3895
3042
|
}
|
|
3896
3043
|
/**
|
|
3897
3044
|
* Apply a transition, returning a new WorkflowInstance (immutable).
|
|
@@ -3902,29 +3049,29 @@ var LocalWorkflowEngine = class {
|
|
|
3902
3049
|
* @returns New WorkflowInstance with updated state and version
|
|
3903
3050
|
* @throws If transition is not valid from current state
|
|
3904
3051
|
*/
|
|
3905
|
-
applyTransition(
|
|
3906
|
-
const def = this.definitions.get(
|
|
3052
|
+
applyTransition(instance2, transitionName, data) {
|
|
3053
|
+
const def = this.definitions.get(instance2.definitionSlug);
|
|
3907
3054
|
if (!def) {
|
|
3908
|
-
throw new Error(`Definition not found: ${
|
|
3055
|
+
throw new Error(`Definition not found: ${instance2.definitionSlug}`);
|
|
3909
3056
|
}
|
|
3910
3057
|
const transition2 = def.transitions.find((t) => t.name === transitionName);
|
|
3911
3058
|
if (!transition2) {
|
|
3912
3059
|
throw new Error(
|
|
3913
|
-
`Transition "${transitionName}" not found in ${
|
|
3060
|
+
`Transition "${transitionName}" not found in ${instance2.definitionSlug}`
|
|
3914
3061
|
);
|
|
3915
3062
|
}
|
|
3916
|
-
if (!transition2.from.includes(
|
|
3063
|
+
if (!transition2.from.includes(instance2.currentState)) {
|
|
3917
3064
|
throw new Error(
|
|
3918
|
-
`Transition "${transitionName}" cannot fire from state "${
|
|
3065
|
+
`Transition "${transitionName}" cannot fire from state "${instance2.currentState}" (allowed from: ${transition2.from.join(", ")})`
|
|
3919
3066
|
);
|
|
3920
3067
|
}
|
|
3921
|
-
const nextState = transition2.to ??
|
|
3922
|
-
const fields = data ? { ...
|
|
3068
|
+
const nextState = transition2.to ?? instance2.currentState;
|
|
3069
|
+
const fields = data ? { ...instance2.fields, ...data } : { ...instance2.fields };
|
|
3923
3070
|
let result = {
|
|
3924
|
-
...
|
|
3071
|
+
...instance2,
|
|
3925
3072
|
currentState: nextState,
|
|
3926
3073
|
fields,
|
|
3927
|
-
version:
|
|
3074
|
+
version: instance2.version + 1,
|
|
3928
3075
|
updatedAt: Date.now()
|
|
3929
3076
|
};
|
|
3930
3077
|
const targetStateDef = def.states.find((s) => s.name === nextState);
|
|
@@ -3997,23 +3144,23 @@ var LocalWorkflowEngine = class {
|
|
|
3997
3144
|
* Apply a transition only if the incoming version is newer.
|
|
3998
3145
|
* Used for P2P sync — skips stale transitions.
|
|
3999
3146
|
*/
|
|
4000
|
-
applyRemoteTransition(
|
|
4001
|
-
if (remoteVersion <=
|
|
3147
|
+
applyRemoteTransition(instance2, transitionName, data, remoteVersion) {
|
|
3148
|
+
if (remoteVersion <= instance2.version) {
|
|
4002
3149
|
return null;
|
|
4003
3150
|
}
|
|
4004
|
-
if (!this.canTransition(
|
|
3151
|
+
if (!this.canTransition(instance2, transitionName)) {
|
|
4005
3152
|
return null;
|
|
4006
3153
|
}
|
|
4007
|
-
const updated = this.applyTransition(
|
|
3154
|
+
const updated = this.applyTransition(instance2, transitionName, data);
|
|
4008
3155
|
return { ...updated, version: remoteVersion };
|
|
4009
3156
|
}
|
|
4010
3157
|
};
|
|
4011
3158
|
|
|
4012
3159
|
// src/local/LocalEngineContext.ts
|
|
4013
|
-
var
|
|
4014
|
-
var LocalEngineContext = (0,
|
|
3160
|
+
var import_react33 = require("react");
|
|
3161
|
+
var LocalEngineContext = (0, import_react33.createContext)(null);
|
|
4015
3162
|
function useLocalEngine() {
|
|
4016
|
-
return (0,
|
|
3163
|
+
return (0, import_react33.useContext)(LocalEngineContext);
|
|
4017
3164
|
}
|
|
4018
3165
|
var LocalEngineProvider = LocalEngineContext.Provider;
|
|
4019
3166
|
|
|
@@ -4270,6 +3417,155 @@ function defineModel(def) {
|
|
|
4270
3417
|
return def;
|
|
4271
3418
|
}
|
|
4272
3419
|
|
|
3420
|
+
// src/config/orchestration-presets.ts
|
|
3421
|
+
var SOLO = {
|
|
3422
|
+
strategy: "solo",
|
|
3423
|
+
evaluation: { pure: "local" },
|
|
3424
|
+
scheduling: { coordinator: "any" },
|
|
3425
|
+
events: { evaluator: "any-subscriber" },
|
|
3426
|
+
errorHandling: { strategy: "manual" },
|
|
3427
|
+
conflicts: { default: "last-writer-wins", fields: {} },
|
|
3428
|
+
visibility: { roles: {}, players: {} },
|
|
3429
|
+
presence: { enabled: false, showEditing: false, showViewing: false },
|
|
3430
|
+
services: {},
|
|
3431
|
+
actionRouting: {}
|
|
3432
|
+
};
|
|
3433
|
+
var CLIENT_SERVER = {
|
|
3434
|
+
strategy: "client-server",
|
|
3435
|
+
evaluation: { pure: "local" },
|
|
3436
|
+
scheduling: { coordinator: "server" },
|
|
3437
|
+
events: { evaluator: "server" },
|
|
3438
|
+
errorHandling: { strategy: "rollback" },
|
|
3439
|
+
conflicts: { default: "last-writer-wins", fields: {} },
|
|
3440
|
+
visibility: { roles: {}, players: {} },
|
|
3441
|
+
presence: { enabled: false, showEditing: false, showViewing: false },
|
|
3442
|
+
services: {},
|
|
3443
|
+
actionRouting: {}
|
|
3444
|
+
};
|
|
3445
|
+
var MULTI_CLIENT = {
|
|
3446
|
+
strategy: "multi-client",
|
|
3447
|
+
evaluation: { pure: "local" },
|
|
3448
|
+
scheduling: { coordinator: "server" },
|
|
3449
|
+
events: { evaluator: "server" },
|
|
3450
|
+
errorHandling: { strategy: "compensate" },
|
|
3451
|
+
conflicts: { default: "last-writer-wins", fields: {} },
|
|
3452
|
+
visibility: { roles: {}, players: {} },
|
|
3453
|
+
presence: { enabled: true, showEditing: true, showViewing: true, conflictHighlight: true },
|
|
3454
|
+
services: {},
|
|
3455
|
+
actionRouting: {}
|
|
3456
|
+
};
|
|
3457
|
+
var SERVICE_MESH = {
|
|
3458
|
+
strategy: "service-mesh",
|
|
3459
|
+
evaluation: { pure: "local" },
|
|
3460
|
+
scheduling: { coordinator: "server" },
|
|
3461
|
+
events: { evaluator: "all" },
|
|
3462
|
+
errorHandling: { strategy: "saga" },
|
|
3463
|
+
conflicts: { default: "first-write-wins", fields: {} },
|
|
3464
|
+
visibility: { roles: {}, players: {} },
|
|
3465
|
+
presence: { enabled: false, showEditing: false, showViewing: false },
|
|
3466
|
+
services: {},
|
|
3467
|
+
actionRouting: {}
|
|
3468
|
+
};
|
|
3469
|
+
var PEER_TO_PEER = {
|
|
3470
|
+
strategy: "peer-to-peer",
|
|
3471
|
+
evaluation: { pure: "local" },
|
|
3472
|
+
scheduling: { coordinator: "any" },
|
|
3473
|
+
events: { evaluator: "any-subscriber" },
|
|
3474
|
+
errorHandling: { strategy: "compensate" },
|
|
3475
|
+
conflicts: { default: "crdt", fields: {} },
|
|
3476
|
+
visibility: { roles: {}, players: {} },
|
|
3477
|
+
presence: { enabled: true, showEditing: true, showViewing: true, conflictHighlight: false },
|
|
3478
|
+
services: {},
|
|
3479
|
+
actionRouting: {}
|
|
3480
|
+
};
|
|
3481
|
+
var HYBRID = {
|
|
3482
|
+
strategy: "hybrid",
|
|
3483
|
+
evaluation: { pure: "local" },
|
|
3484
|
+
scheduling: { coordinator: "server" },
|
|
3485
|
+
events: { evaluator: "server" },
|
|
3486
|
+
errorHandling: { strategy: "saga" },
|
|
3487
|
+
conflicts: { default: "last-writer-wins", fields: {} },
|
|
3488
|
+
visibility: { roles: {}, players: {} },
|
|
3489
|
+
presence: { enabled: true, showEditing: true, showViewing: false, conflictHighlight: false },
|
|
3490
|
+
services: {},
|
|
3491
|
+
actionRouting: {}
|
|
3492
|
+
};
|
|
3493
|
+
var HEADLESS = {
|
|
3494
|
+
strategy: "headless",
|
|
3495
|
+
evaluation: { pure: "local" },
|
|
3496
|
+
// expression engine runs server-local (native Rust, fastest)
|
|
3497
|
+
scheduling: { coordinator: "server" },
|
|
3498
|
+
// server manages cron/interval/timeout
|
|
3499
|
+
events: { evaluator: "server" },
|
|
3500
|
+
// server matches events, no clients involved
|
|
3501
|
+
errorHandling: { strategy: "compensate" },
|
|
3502
|
+
conflicts: { default: "first-write-wins", fields: {} },
|
|
3503
|
+
// no concurrent clients
|
|
3504
|
+
visibility: { roles: {}, players: {} },
|
|
3505
|
+
presence: { enabled: false, showEditing: false, showViewing: false, conflictHighlight: false },
|
|
3506
|
+
services: {},
|
|
3507
|
+
actionRouting: {}
|
|
3508
|
+
};
|
|
3509
|
+
var ORCHESTRATION_PRESETS = {
|
|
3510
|
+
"solo": SOLO,
|
|
3511
|
+
"client-server": CLIENT_SERVER,
|
|
3512
|
+
"multi-client": MULTI_CLIENT,
|
|
3513
|
+
"service-mesh": SERVICE_MESH,
|
|
3514
|
+
"peer-to-peer": PEER_TO_PEER,
|
|
3515
|
+
"hybrid": HYBRID,
|
|
3516
|
+
"headless": HEADLESS,
|
|
3517
|
+
"custom": CLIENT_SERVER
|
|
3518
|
+
// custom uses client-server as base
|
|
3519
|
+
};
|
|
3520
|
+
var DEFAULT_RESOLVED = {
|
|
3521
|
+
strategy: "client-server",
|
|
3522
|
+
evaluation: { pure: "local" },
|
|
3523
|
+
scheduling: { coordinator: "server" },
|
|
3524
|
+
events: { evaluator: "server" },
|
|
3525
|
+
errorHandling: { strategy: "rollback" },
|
|
3526
|
+
conflicts: { default: "last-writer-wins", fields: {} },
|
|
3527
|
+
visibility: { roles: {}, players: {} },
|
|
3528
|
+
presence: { enabled: false, showEditing: false, showViewing: false, conflictHighlight: false },
|
|
3529
|
+
services: {},
|
|
3530
|
+
actionRouting: {}
|
|
3531
|
+
};
|
|
3532
|
+
function resolveOrchestration(config) {
|
|
3533
|
+
if (!config) return { ...DEFAULT_RESOLVED };
|
|
3534
|
+
const strategy = config.strategy || "client-server";
|
|
3535
|
+
const preset = ORCHESTRATION_PRESETS[strategy] || CLIENT_SERVER;
|
|
3536
|
+
return {
|
|
3537
|
+
strategy,
|
|
3538
|
+
evaluation: {
|
|
3539
|
+
pure: config.evaluation?.pure ?? preset.evaluation?.pure ?? "local"
|
|
3540
|
+
},
|
|
3541
|
+
scheduling: {
|
|
3542
|
+
coordinator: config.scheduling?.coordinator ?? preset.scheduling?.coordinator ?? "server"
|
|
3543
|
+
},
|
|
3544
|
+
events: {
|
|
3545
|
+
evaluator: config.events?.evaluator ?? preset.events?.evaluator ?? "server"
|
|
3546
|
+
},
|
|
3547
|
+
errorHandling: {
|
|
3548
|
+
strategy: config.errorHandling?.strategy ?? preset.errorHandling?.strategy ?? "rollback"
|
|
3549
|
+
},
|
|
3550
|
+
conflicts: {
|
|
3551
|
+
default: config.conflicts?.default ?? preset.conflicts?.default ?? "last-writer-wins",
|
|
3552
|
+
fields: { ...preset.conflicts?.fields || {}, ...config.conflicts?.fields || {} }
|
|
3553
|
+
},
|
|
3554
|
+
visibility: {
|
|
3555
|
+
roles: { ...preset.visibility?.roles || {}, ...config.visibility?.roles || {} },
|
|
3556
|
+
players: { ...preset.visibility?.players || {}, ...config.visibility?.players || {} }
|
|
3557
|
+
},
|
|
3558
|
+
presence: {
|
|
3559
|
+
enabled: config.presence?.enabled ?? preset.presence?.enabled ?? false,
|
|
3560
|
+
showEditing: config.presence?.showEditing ?? preset.presence?.showEditing ?? false,
|
|
3561
|
+
showViewing: config.presence?.showViewing ?? preset.presence?.showViewing ?? false,
|
|
3562
|
+
conflictHighlight: config.presence?.conflictHighlight ?? preset.presence?.conflictHighlight ?? false
|
|
3563
|
+
},
|
|
3564
|
+
services: { ...preset.services || {}, ...config.services || {} },
|
|
3565
|
+
actionRouting: { ...preset.actionRouting || {}, ...config.actionRouting || {} }
|
|
3566
|
+
};
|
|
3567
|
+
}
|
|
3568
|
+
|
|
4273
3569
|
// src/config/defineBlueprint.ts
|
|
4274
3570
|
function defineBlueprint(config) {
|
|
4275
3571
|
if (!config.slug) {
|
|
@@ -4383,13 +3679,13 @@ function inState(state2) {
|
|
|
4383
3679
|
function notInState(state2) {
|
|
4384
3680
|
return { type: "expression", expression: `current_state != "${state2}"` };
|
|
4385
3681
|
}
|
|
4386
|
-
function
|
|
3682
|
+
function and(...conditions) {
|
|
4387
3683
|
return { AND: conditions.map(normalize) };
|
|
4388
3684
|
}
|
|
4389
|
-
function
|
|
3685
|
+
function or(...conditions) {
|
|
4390
3686
|
return { OR: conditions.map(normalize) };
|
|
4391
3687
|
}
|
|
4392
|
-
function
|
|
3688
|
+
function not(condition) {
|
|
4393
3689
|
const c = normalize(condition);
|
|
4394
3690
|
if (c.type === "expression" && c.expression) {
|
|
4395
3691
|
return { type: "expression", expression: `NOT(${c.expression})` };
|
|
@@ -4434,7 +3730,7 @@ function refHasAnyRole(slug, lookupField, lookupValue, roles) {
|
|
|
4434
3730
|
}
|
|
4435
3731
|
|
|
4436
3732
|
// src/hooks/useModel.ts
|
|
4437
|
-
var
|
|
3733
|
+
var import_react34 = require("react");
|
|
4438
3734
|
function getDefaultFields(definition) {
|
|
4439
3735
|
const defaults = {};
|
|
4440
3736
|
for (const [key, field2] of Object.entries(definition.fields)) {
|
|
@@ -4489,18 +3785,18 @@ function useModel(definition, options = {}) {
|
|
|
4489
3785
|
if (options.state) queryParams.state = options.state;
|
|
4490
3786
|
const query = useQuery(slug, queryParams);
|
|
4491
3787
|
const mutation = useMutation(slug);
|
|
4492
|
-
const
|
|
4493
|
-
const instanceId =
|
|
4494
|
-
const currentState =
|
|
4495
|
-
const instanceFields =
|
|
4496
|
-
const defaultFields = (0,
|
|
4497
|
-
const fields = (0,
|
|
3788
|
+
const instance2 = query.data?.[0];
|
|
3789
|
+
const instanceId = instance2?.id ?? null;
|
|
3790
|
+
const currentState = instance2?.currentState ?? "";
|
|
3791
|
+
const instanceFields = instance2?.fields ?? null;
|
|
3792
|
+
const defaultFields = (0, import_react34.useMemo)(() => getDefaultFields(definition), [definition]);
|
|
3793
|
+
const fields = (0, import_react34.useMemo)(() => {
|
|
4498
3794
|
if (!instanceFields) return defaultFields;
|
|
4499
3795
|
return { ...defaultFields, ...instanceFields };
|
|
4500
3796
|
}, [instanceFields, defaultFields]);
|
|
4501
|
-
const instanceIdRef = (0,
|
|
3797
|
+
const instanceIdRef = (0, import_react34.useRef)(instanceId);
|
|
4502
3798
|
instanceIdRef.current = instanceId;
|
|
4503
|
-
const trigger = (0,
|
|
3799
|
+
const trigger = (0, import_react34.useCallback)(async (name, input) => {
|
|
4504
3800
|
const id = instanceIdRef.current;
|
|
4505
3801
|
if (!id) {
|
|
4506
3802
|
throw new Error(`useModel(${slug}): No instance loaded. Cannot trigger '${name}'.`);
|
|
@@ -4508,12 +3804,12 @@ function useModel(definition, options = {}) {
|
|
|
4508
3804
|
await mutation.transition(id, name, input);
|
|
4509
3805
|
await query.refetch();
|
|
4510
3806
|
}, [slug, mutation, query]);
|
|
4511
|
-
const create = (0,
|
|
3807
|
+
const create = (0, import_react34.useCallback)(async (input) => {
|
|
4512
3808
|
const id = await mutation.create(input);
|
|
4513
3809
|
await query.refetch();
|
|
4514
3810
|
return id;
|
|
4515
3811
|
}, [mutation, query]);
|
|
4516
|
-
const update = (0,
|
|
3812
|
+
const update = (0, import_react34.useCallback)(async (fieldUpdates) => {
|
|
4517
3813
|
const id = instanceIdRef.current;
|
|
4518
3814
|
if (!id) {
|
|
4519
3815
|
throw new Error(`useModel(${slug}): No instance loaded. Cannot update.`);
|
|
@@ -4542,27 +3838,27 @@ function useCollection(definition, options = {}) {
|
|
|
4542
3838
|
const slug = definition.slug;
|
|
4543
3839
|
const query = useQuery(slug, options);
|
|
4544
3840
|
const mutation = useMutation(slug);
|
|
4545
|
-
const items = (0,
|
|
4546
|
-
return (query.data || []).map((
|
|
4547
|
-
id:
|
|
4548
|
-
fields:
|
|
4549
|
-
state:
|
|
3841
|
+
const items = (0, import_react34.useMemo)(() => {
|
|
3842
|
+
return (query.data || []).map((instance2) => ({
|
|
3843
|
+
id: instance2.id,
|
|
3844
|
+
fields: instance2.fields ?? {},
|
|
3845
|
+
state: instance2.currentState ?? ""
|
|
4550
3846
|
}));
|
|
4551
3847
|
}, [query.data]);
|
|
4552
|
-
const trigger = (0,
|
|
3848
|
+
const trigger = (0, import_react34.useCallback)(async (instanceId, name, input) => {
|
|
4553
3849
|
await mutation.transition(instanceId, name, input);
|
|
4554
3850
|
await query.refetch();
|
|
4555
3851
|
}, [mutation, query]);
|
|
4556
|
-
const create = (0,
|
|
3852
|
+
const create = (0, import_react34.useCallback)(async (input) => {
|
|
4557
3853
|
const id = await mutation.create(input);
|
|
4558
3854
|
await query.refetch();
|
|
4559
3855
|
return id;
|
|
4560
3856
|
}, [mutation, query]);
|
|
4561
|
-
const update = (0,
|
|
3857
|
+
const update = (0, import_react34.useCallback)(async (instanceId, fieldUpdates) => {
|
|
4562
3858
|
await mutation.update(instanceId, fieldUpdates);
|
|
4563
3859
|
await query.refetch();
|
|
4564
3860
|
}, [mutation, query]);
|
|
4565
|
-
const remove = (0,
|
|
3861
|
+
const remove = (0, import_react34.useCallback)(async (instanceId) => {
|
|
4566
3862
|
await mutation.remove(instanceId);
|
|
4567
3863
|
await query.refetch();
|
|
4568
3864
|
}, [mutation, query]);
|
|
@@ -4586,7 +3882,7 @@ function useCollection(definition, options = {}) {
|
|
|
4586
3882
|
function stub(displayName) {
|
|
4587
3883
|
const Component = () => {
|
|
4588
3884
|
throw new Error(
|
|
4589
|
-
`<${displayName}> is a compile-time stub from @
|
|
3885
|
+
`<${displayName}> is a compile-time stub from @mmapp/react/atoms. It should only appear in .workflow.tsx files processed by the compiler. At runtime, use the ComponentTreeRenderer which resolves "${displayName}" from the component registry.`
|
|
4590
3886
|
);
|
|
4591
3887
|
};
|
|
4592
3888
|
Component.displayName = displayName;
|
|
@@ -4713,7 +4009,7 @@ function djb2Hash(str) {
|
|
|
4713
4009
|
}
|
|
4714
4010
|
|
|
4715
4011
|
// src/authoring.ts
|
|
4716
|
-
function
|
|
4012
|
+
function useState21(_defaultOrKey) {
|
|
4717
4013
|
return [void 0, () => {
|
|
4718
4014
|
}];
|
|
4719
4015
|
}
|
|
@@ -4724,10 +4020,10 @@ function defineWorkspace(config) {
|
|
|
4724
4020
|
}
|
|
4725
4021
|
|
|
4726
4022
|
// src/hooks/useModule.ts
|
|
4727
|
-
var
|
|
4023
|
+
var import_react35 = require("react");
|
|
4728
4024
|
function useModule(slug, config = {}, options = {}) {
|
|
4729
4025
|
const { enabled = true } = options;
|
|
4730
|
-
return (0,
|
|
4026
|
+
return (0, import_react35.useMemo)(() => ({
|
|
4731
4027
|
slug,
|
|
4732
4028
|
config,
|
|
4733
4029
|
isLoaded: enabled
|
|
@@ -4735,7 +4031,7 @@ function useModule(slug, config = {}, options = {}) {
|
|
|
4735
4031
|
}
|
|
4736
4032
|
|
|
4737
4033
|
// src/hooks/useModuleConfig.ts
|
|
4738
|
-
var
|
|
4034
|
+
var import_react36 = require("react");
|
|
4739
4035
|
var installedModulesStore = [];
|
|
4740
4036
|
var configDefaultsStore = /* @__PURE__ */ new Map();
|
|
4741
4037
|
function setInstalledModules(modules) {
|
|
@@ -4751,7 +4047,7 @@ function getInstalledModules() {
|
|
|
4751
4047
|
return installedModulesStore;
|
|
4752
4048
|
}
|
|
4753
4049
|
function useModuleConfig(moduleSlug) {
|
|
4754
|
-
return (0,
|
|
4050
|
+
return (0, import_react36.useMemo)(() => {
|
|
4755
4051
|
const installed = getInstalledModule(moduleSlug);
|
|
4756
4052
|
const defaults = configDefaultsStore.get(moduleSlug) ?? {};
|
|
4757
4053
|
const persisted = persistedConfigStore.get(moduleSlug) ?? {};
|
|
@@ -4799,8 +4095,8 @@ async function updateDefinitionConfig(values, definitionId) {
|
|
|
4799
4095
|
}
|
|
4800
4096
|
function useModuleConfigWithMutation(moduleSlug) {
|
|
4801
4097
|
const config = useModuleConfig(moduleSlug);
|
|
4802
|
-
const [isSaving, setIsSaving] = (0,
|
|
4803
|
-
const updateConfig = (0,
|
|
4098
|
+
const [isSaving, setIsSaving] = (0, import_react36.useState)(false);
|
|
4099
|
+
const updateConfig = (0, import_react36.useCallback)(async (values) => {
|
|
4804
4100
|
setIsSaving(true);
|
|
4805
4101
|
try {
|
|
4806
4102
|
return await updateDefinitionConfig(values);
|
|
@@ -6313,7 +5609,7 @@ function approval(config = {}) {
|
|
|
6313
5609
|
}
|
|
6314
5610
|
function escalation(config) {
|
|
6315
5611
|
const {
|
|
6316
|
-
timeout,
|
|
5612
|
+
timeout: timeout2,
|
|
6317
5613
|
notifyRole = "admin",
|
|
6318
5614
|
fromState = "pending_approval",
|
|
6319
5615
|
escalatedState = "escalated"
|
|
@@ -6325,7 +5621,7 @@ function escalation(config) {
|
|
|
6325
5621
|
});
|
|
6326
5622
|
if (def.states[fromState]) {
|
|
6327
5623
|
def.states[fromState].timeout = {
|
|
6328
|
-
duration:
|
|
5624
|
+
duration: timeout2,
|
|
6329
5625
|
fallback: { transition: "escalate" }
|
|
6330
5626
|
};
|
|
6331
5627
|
}
|
|
@@ -6344,8 +5640,8 @@ function escalation(config) {
|
|
|
6344
5640
|
from: fromState,
|
|
6345
5641
|
to: escalatedState,
|
|
6346
5642
|
auto: true,
|
|
6347
|
-
description: `Auto-escalate after ${
|
|
6348
|
-
actions: [logEvent("escalated", { timeout })]
|
|
5643
|
+
description: `Auto-escalate after ${timeout2}`,
|
|
5644
|
+
actions: [logEvent("escalated", { timeout: timeout2 })]
|
|
6349
5645
|
}
|
|
6350
5646
|
});
|
|
6351
5647
|
return def;
|
|
@@ -7003,7 +6299,8 @@ function describeModel(def) {
|
|
|
7003
6299
|
}
|
|
7004
6300
|
|
|
7005
6301
|
// src/hooks/usePlayer.ts
|
|
7006
|
-
var
|
|
6302
|
+
var import_react37 = require("react");
|
|
6303
|
+
var import_player_core2 = require("@mmapp/player-core");
|
|
7007
6304
|
|
|
7008
6305
|
// src/logger.ts
|
|
7009
6306
|
var debugEnabled = false;
|
|
@@ -7043,18 +6340,18 @@ function computePlayerState(sm) {
|
|
|
7043
6340
|
};
|
|
7044
6341
|
}
|
|
7045
6342
|
function usePlayer(config) {
|
|
7046
|
-
const configRef = (0,
|
|
6343
|
+
const configRef = (0, import_react37.useRef)(config);
|
|
7047
6344
|
configRef.current = config;
|
|
7048
|
-
(0,
|
|
6345
|
+
(0, import_react37.useEffect)(() => {
|
|
7049
6346
|
if (config.debug) setPlayerDebug(true);
|
|
7050
6347
|
}, [config.debug]);
|
|
7051
|
-
const evaluator = (0,
|
|
7052
|
-
return createEvaluator({
|
|
6348
|
+
const evaluator = (0, import_react37.useMemo)(() => {
|
|
6349
|
+
return (0, import_player_core2.createEvaluator)({
|
|
7053
6350
|
functions: config.functions ?? [],
|
|
7054
|
-
failurePolicy: WEB_FAILURE_POLICIES.EVENT_REACTION
|
|
6351
|
+
failurePolicy: import_player_core2.WEB_FAILURE_POLICIES.EVENT_REACTION
|
|
7055
6352
|
});
|
|
7056
6353
|
}, [config.definition.id]);
|
|
7057
|
-
const engine = (0,
|
|
6354
|
+
const engine = (0, import_react37.useMemo)(() => {
|
|
7058
6355
|
const actionHandlers = /* @__PURE__ */ new Map();
|
|
7059
6356
|
if (config.actionHandlers) {
|
|
7060
6357
|
for (const [type, handler] of Object.entries(config.actionHandlers)) {
|
|
@@ -7082,14 +6379,14 @@ function usePlayer(config) {
|
|
|
7082
6379
|
});
|
|
7083
6380
|
}
|
|
7084
6381
|
});
|
|
7085
|
-
const sm2 = new StateMachine(
|
|
6382
|
+
const sm2 = new import_player_core2.StateMachine(
|
|
7086
6383
|
config.definition,
|
|
7087
6384
|
config.initialData ?? {},
|
|
7088
6385
|
{ evaluator, actionHandlers }
|
|
7089
6386
|
);
|
|
7090
6387
|
smRef = sm2;
|
|
7091
|
-
const eventBus2 = new EventBus();
|
|
7092
|
-
const dispatcher = new ActionDispatcher();
|
|
6388
|
+
const eventBus2 = new import_player_core2.EventBus();
|
|
6389
|
+
const dispatcher = new import_player_core2.ActionDispatcher();
|
|
7093
6390
|
dispatcher.register("set_field", (cfg) => {
|
|
7094
6391
|
if (smRef && typeof cfg.field === "string") {
|
|
7095
6392
|
smRef.setField(cfg.field, cfg.value);
|
|
@@ -7108,8 +6405,8 @@ function usePlayer(config) {
|
|
|
7108
6405
|
return { sm: sm2, eventBus: eventBus2, dispatcher };
|
|
7109
6406
|
}, [config.definition.id, evaluator]);
|
|
7110
6407
|
const { sm, eventBus } = engine;
|
|
7111
|
-
const [playerState, setPlayerState] = (0,
|
|
7112
|
-
(0,
|
|
6408
|
+
const [playerState, setPlayerState] = (0, import_react37.useState)(() => computePlayerState(sm));
|
|
6409
|
+
(0, import_react37.useEffect)(() => {
|
|
7113
6410
|
const stateDef = sm.getCurrentStateDefinition();
|
|
7114
6411
|
if (!stateDef?.on_event?.length) return;
|
|
7115
6412
|
const unsubs = [];
|
|
@@ -7173,7 +6470,7 @@ function usePlayer(config) {
|
|
|
7173
6470
|
for (const unsub of unsubs) unsub();
|
|
7174
6471
|
};
|
|
7175
6472
|
}, [sm, eventBus, evaluator, engine.dispatcher, playerState.currentState]);
|
|
7176
|
-
(0,
|
|
6473
|
+
(0, import_react37.useEffect)(() => {
|
|
7177
6474
|
const unsub = sm.on((event) => {
|
|
7178
6475
|
if (event.type === "transition" || event.type === "state_enter") {
|
|
7179
6476
|
setPlayerState(computePlayerState(sm));
|
|
@@ -7189,7 +6486,7 @@ function usePlayer(config) {
|
|
|
7189
6486
|
});
|
|
7190
6487
|
return unsub;
|
|
7191
6488
|
}, [sm]);
|
|
7192
|
-
const transition2 = (0,
|
|
6489
|
+
const transition2 = (0, import_react37.useCallback)(
|
|
7193
6490
|
async (name, data) => {
|
|
7194
6491
|
playerLog({
|
|
7195
6492
|
level: "info",
|
|
@@ -7216,20 +6513,20 @@ function usePlayer(config) {
|
|
|
7216
6513
|
},
|
|
7217
6514
|
[sm]
|
|
7218
6515
|
);
|
|
7219
|
-
const setField2 = (0,
|
|
6516
|
+
const setField2 = (0, import_react37.useCallback)(
|
|
7220
6517
|
(field2, value) => {
|
|
7221
6518
|
sm.setField(field2, value);
|
|
7222
6519
|
setPlayerState(computePlayerState(sm));
|
|
7223
6520
|
},
|
|
7224
6521
|
[sm]
|
|
7225
6522
|
);
|
|
7226
|
-
const setMemory = (0,
|
|
6523
|
+
const setMemory = (0, import_react37.useCallback)(
|
|
7227
6524
|
(key, value) => {
|
|
7228
6525
|
sm.setMemory(key, value);
|
|
7229
6526
|
},
|
|
7230
6527
|
[sm]
|
|
7231
6528
|
);
|
|
7232
|
-
const publishEvent = (0,
|
|
6529
|
+
const publishEvent = (0, import_react37.useCallback)(
|
|
7233
6530
|
(topic, payload) => {
|
|
7234
6531
|
playerLog({
|
|
7235
6532
|
level: "debug",
|
|
@@ -7255,11 +6552,11 @@ function usePlayer(config) {
|
|
|
7255
6552
|
}
|
|
7256
6553
|
|
|
7257
6554
|
// src/hooks/useDomainSubscription.ts
|
|
7258
|
-
var
|
|
6555
|
+
var import_react38 = require("react");
|
|
7259
6556
|
function useDomainSubscription(eventBus, transport, config) {
|
|
7260
|
-
const configRef = (0,
|
|
6557
|
+
const configRef = (0, import_react38.useRef)(config);
|
|
7261
6558
|
configRef.current = config;
|
|
7262
|
-
(0,
|
|
6559
|
+
(0, import_react38.useEffect)(() => {
|
|
7263
6560
|
if (!transport || config.enabled === false) return;
|
|
7264
6561
|
const unsub = transport.subscribe(
|
|
7265
6562
|
{
|
|
@@ -7312,11 +6609,11 @@ function useDomainSubscription(eventBus, transport, config) {
|
|
|
7312
6609
|
}
|
|
7313
6610
|
|
|
7314
6611
|
// src/hooks/useExperienceState.ts
|
|
7315
|
-
var
|
|
6612
|
+
var import_react39 = require("react");
|
|
7316
6613
|
function useExperienceState(player, selector) {
|
|
7317
|
-
const selectorRef = (0,
|
|
6614
|
+
const selectorRef = (0, import_react39.useRef)(selector);
|
|
7318
6615
|
selectorRef.current = selector;
|
|
7319
|
-
const getSnapshot = (0,
|
|
6616
|
+
const getSnapshot = (0, import_react39.useCallback)(() => {
|
|
7320
6617
|
return selectorRef.current({
|
|
7321
6618
|
currentState: player.currentState,
|
|
7322
6619
|
stateData: player.stateData,
|
|
@@ -7332,20 +6629,20 @@ function useStateField(player, field2, defaultValue) {
|
|
|
7332
6629
|
}
|
|
7333
6630
|
|
|
7334
6631
|
// src/hooks/useComputed.ts
|
|
7335
|
-
var
|
|
6632
|
+
var import_react40 = require("react");
|
|
7336
6633
|
function useComputed(_name, compute, options) {
|
|
7337
6634
|
const mode = options?.mode ?? "read-time";
|
|
7338
6635
|
const deps = options?.deps ?? [];
|
|
7339
|
-
const computeRef = (0,
|
|
6636
|
+
const computeRef = (0, import_react40.useRef)(compute);
|
|
7340
6637
|
computeRef.current = compute;
|
|
7341
6638
|
if (mode === "read-time") {
|
|
7342
|
-
return (0,
|
|
6639
|
+
return (0, import_react40.useMemo)(() => computeRef.current(), [
|
|
7343
6640
|
// We intentionally depend on deps.join to recompute when tracked fields change
|
|
7344
6641
|
// The actual dependency tracking happens at the compiler level
|
|
7345
6642
|
deps.join(",")
|
|
7346
6643
|
]);
|
|
7347
6644
|
}
|
|
7348
|
-
return (0,
|
|
6645
|
+
return (0, import_react40.useMemo)(() => computeRef.current(), [deps.join(",")]);
|
|
7349
6646
|
}
|
|
7350
6647
|
function useComputedWithMeta(name, compute, options) {
|
|
7351
6648
|
const value = useComputed(name, compute, options);
|
|
@@ -7360,25 +6657,25 @@ function useComputedWithMeta(name, compute, options) {
|
|
|
7360
6657
|
}
|
|
7361
6658
|
|
|
7362
6659
|
// src/components/PlayerProvider.tsx
|
|
7363
|
-
var
|
|
6660
|
+
var import_react41 = require("react");
|
|
7364
6661
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
7365
|
-
var PlayerContext = (0,
|
|
6662
|
+
var PlayerContext = (0, import_react41.createContext)(null);
|
|
7366
6663
|
function PlayerProvider({ player, children }) {
|
|
7367
6664
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PlayerContext.Provider, { value: player, children });
|
|
7368
6665
|
}
|
|
7369
6666
|
function usePlayerContext() {
|
|
7370
|
-
const ctx = (0,
|
|
6667
|
+
const ctx = (0, import_react41.useContext)(PlayerContext);
|
|
7371
6668
|
if (!ctx) {
|
|
7372
6669
|
throw new Error("usePlayerContext must be used within a <PlayerProvider>");
|
|
7373
6670
|
}
|
|
7374
6671
|
return ctx;
|
|
7375
6672
|
}
|
|
7376
6673
|
function usePlayerContextSafe() {
|
|
7377
|
-
return (0,
|
|
6674
|
+
return (0, import_react41.useContext)(PlayerContext);
|
|
7378
6675
|
}
|
|
7379
6676
|
|
|
7380
6677
|
// src/components/ExperienceWorkflowBridge.tsx
|
|
7381
|
-
var
|
|
6678
|
+
var import_react42 = require("react");
|
|
7382
6679
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
7383
6680
|
function ExperienceWorkflowBridgeInner({
|
|
7384
6681
|
definition,
|
|
@@ -7396,7 +6693,7 @@ function ExperienceWorkflowBridgeInner({
|
|
|
7396
6693
|
actionHandlers,
|
|
7397
6694
|
debug
|
|
7398
6695
|
});
|
|
7399
|
-
const viewConfig = (0,
|
|
6696
|
+
const viewConfig = (0, import_react42.useMemo)(() => {
|
|
7400
6697
|
if (!definition.state_views) return void 0;
|
|
7401
6698
|
return definition.state_views[player.currentState];
|
|
7402
6699
|
}, [definition.state_views, player.currentState]);
|
|
@@ -7431,7 +6728,7 @@ function ExperienceWorkflowBridge(props) {
|
|
|
7431
6728
|
}
|
|
7432
6729
|
|
|
7433
6730
|
// src/components/atoms/index.tsx
|
|
7434
|
-
var
|
|
6731
|
+
var import_react43 = __toESM(require("react"));
|
|
7435
6732
|
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
7436
6733
|
|
|
7437
6734
|
// src/loader/experience-workflow-loader.ts
|
|
@@ -7752,7 +7049,7 @@ var BrowserPlayer = class {
|
|
|
7752
7049
|
this.ensureInitialized();
|
|
7753
7050
|
const id = crypto.randomUUID();
|
|
7754
7051
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
7755
|
-
const
|
|
7052
|
+
const instance2 = {
|
|
7756
7053
|
id,
|
|
7757
7054
|
definitionId: options.definitionId ?? definitionSlug,
|
|
7758
7055
|
definitionSlug,
|
|
@@ -7764,15 +7061,15 @@ var BrowserPlayer = class {
|
|
|
7764
7061
|
createdAt: now,
|
|
7765
7062
|
updatedAt: now
|
|
7766
7063
|
};
|
|
7767
|
-
await this.putInstance(
|
|
7064
|
+
await this.putInstance(instance2);
|
|
7768
7065
|
this.log("info", `Instance created: ${id} (${definitionSlug})`);
|
|
7769
7066
|
this.emit({
|
|
7770
7067
|
type: "instance:created",
|
|
7771
7068
|
instanceId: id,
|
|
7772
|
-
data: { definitionSlug, currentState:
|
|
7069
|
+
data: { definitionSlug, currentState: instance2.currentState },
|
|
7773
7070
|
timestamp: Date.now()
|
|
7774
7071
|
});
|
|
7775
|
-
return
|
|
7072
|
+
return instance2;
|
|
7776
7073
|
}
|
|
7777
7074
|
/** Get an instance by ID. */
|
|
7778
7075
|
async getInstance(id) {
|
|
@@ -7781,13 +7078,13 @@ var BrowserPlayer = class {
|
|
|
7781
7078
|
}
|
|
7782
7079
|
/** Get the current state of an instance. */
|
|
7783
7080
|
async getState(id) {
|
|
7784
|
-
const
|
|
7785
|
-
if (!
|
|
7081
|
+
const instance2 = await this.getInstance(id);
|
|
7082
|
+
if (!instance2) return null;
|
|
7786
7083
|
return {
|
|
7787
|
-
currentState:
|
|
7788
|
-
status:
|
|
7789
|
-
stateData:
|
|
7790
|
-
lockVersion:
|
|
7084
|
+
currentState: instance2.currentState,
|
|
7085
|
+
status: instance2.status,
|
|
7086
|
+
stateData: instance2.stateData,
|
|
7087
|
+
lockVersion: instance2.lockVersion
|
|
7791
7088
|
};
|
|
7792
7089
|
}
|
|
7793
7090
|
/**
|
|
@@ -7798,34 +7095,34 @@ var BrowserPlayer = class {
|
|
|
7798
7095
|
*/
|
|
7799
7096
|
async transition(instanceId, transitionName, data = {}) {
|
|
7800
7097
|
this.ensureInitialized();
|
|
7801
|
-
const
|
|
7802
|
-
if (!
|
|
7098
|
+
const instance2 = await this.getInstanceFromDb(instanceId);
|
|
7099
|
+
if (!instance2) {
|
|
7803
7100
|
return {
|
|
7804
7101
|
success: false,
|
|
7805
7102
|
instance: null,
|
|
7806
7103
|
error: `Instance ${instanceId} not found`
|
|
7807
7104
|
};
|
|
7808
7105
|
}
|
|
7809
|
-
if (
|
|
7106
|
+
if (instance2.status !== "ACTIVE") {
|
|
7810
7107
|
return {
|
|
7811
7108
|
success: false,
|
|
7812
|
-
instance,
|
|
7813
|
-
error: `Instance is ${
|
|
7109
|
+
instance: instance2,
|
|
7110
|
+
error: `Instance is ${instance2.status}, cannot transition`
|
|
7814
7111
|
};
|
|
7815
7112
|
}
|
|
7816
7113
|
try {
|
|
7817
|
-
const newStateData = { ...
|
|
7818
|
-
const newLockVersion =
|
|
7114
|
+
const newStateData = { ...instance2.stateData, ...data };
|
|
7115
|
+
const newLockVersion = instance2.lockVersion + 1;
|
|
7819
7116
|
if (this.wasm.execute_transition) {
|
|
7820
7117
|
const request = {
|
|
7821
7118
|
instance: {
|
|
7822
|
-
id:
|
|
7823
|
-
definition_id:
|
|
7824
|
-
current_state:
|
|
7825
|
-
status:
|
|
7119
|
+
id: instance2.id,
|
|
7120
|
+
definition_id: instance2.definitionId,
|
|
7121
|
+
current_state: instance2.currentState,
|
|
7122
|
+
status: instance2.status,
|
|
7826
7123
|
state_data: newStateData,
|
|
7827
|
-
memory:
|
|
7828
|
-
execution_lock_version:
|
|
7124
|
+
memory: instance2.memory,
|
|
7125
|
+
execution_lock_version: instance2.lockVersion
|
|
7829
7126
|
},
|
|
7830
7127
|
transition_name: transitionName,
|
|
7831
7128
|
actor_id: this.peerId,
|
|
@@ -7834,26 +7131,26 @@ var BrowserPlayer = class {
|
|
|
7834
7131
|
const resultJson = this.wasm.execute_transition(JSON.stringify(request));
|
|
7835
7132
|
const result = JSON.parse(resultJson);
|
|
7836
7133
|
if (result.success === false || result.error) {
|
|
7837
|
-
return { success: false, instance, error: result.error ?? "Transition failed" };
|
|
7134
|
+
return { success: false, instance: instance2, error: result.error ?? "Transition failed" };
|
|
7838
7135
|
}
|
|
7839
|
-
|
|
7840
|
-
|
|
7841
|
-
|
|
7842
|
-
|
|
7136
|
+
instance2.currentState = result.to_state ?? instance2.currentState;
|
|
7137
|
+
instance2.status = result.status ?? instance2.status;
|
|
7138
|
+
instance2.stateData = result.state_data ?? newStateData;
|
|
7139
|
+
instance2.memory = result.memory ?? instance2.memory;
|
|
7843
7140
|
} else {
|
|
7844
|
-
|
|
7141
|
+
instance2.stateData = newStateData;
|
|
7845
7142
|
}
|
|
7846
|
-
|
|
7847
|
-
|
|
7848
|
-
await this.putInstance(
|
|
7143
|
+
instance2.lockVersion = newLockVersion;
|
|
7144
|
+
instance2.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
7145
|
+
await this.putInstance(instance2);
|
|
7849
7146
|
this.log("info", `Transition: ${instanceId} ${transitionName}`);
|
|
7850
7147
|
this.emit({
|
|
7851
7148
|
type: "instance:transition",
|
|
7852
7149
|
instanceId,
|
|
7853
7150
|
data: {
|
|
7854
7151
|
transitionName,
|
|
7855
|
-
fromState:
|
|
7856
|
-
toState:
|
|
7152
|
+
fromState: instance2.currentState,
|
|
7153
|
+
toState: instance2.currentState,
|
|
7857
7154
|
lockVersion: newLockVersion
|
|
7858
7155
|
},
|
|
7859
7156
|
timestamp: Date.now()
|
|
@@ -7863,7 +7160,7 @@ var BrowserPlayer = class {
|
|
|
7863
7160
|
type: "TransitionReplication",
|
|
7864
7161
|
instance_id: instanceId,
|
|
7865
7162
|
transition_name: transitionName,
|
|
7866
|
-
state_data:
|
|
7163
|
+
state_data: instance2.stateData,
|
|
7867
7164
|
lock_version: newLockVersion
|
|
7868
7165
|
});
|
|
7869
7166
|
const envelope = this.wasm.sign_envelope(this.secretKeyHex, payload);
|
|
@@ -7873,11 +7170,11 @@ var BrowserPlayer = class {
|
|
|
7873
7170
|
envelope
|
|
7874
7171
|
}));
|
|
7875
7172
|
}
|
|
7876
|
-
return { success: true, instance };
|
|
7173
|
+
return { success: true, instance: instance2 };
|
|
7877
7174
|
} catch (err) {
|
|
7878
7175
|
const error = err instanceof Error ? err.message : String(err);
|
|
7879
7176
|
this.log("error", `Transition failed: ${error}`);
|
|
7880
|
-
return { success: false, instance, error };
|
|
7177
|
+
return { success: false, instance: instance2, error };
|
|
7881
7178
|
}
|
|
7882
7179
|
}
|
|
7883
7180
|
// ─── Subscriptions ──────────────────────────────────────────────────
|
|
@@ -7957,12 +7254,12 @@ var BrowserPlayer = class {
|
|
|
7957
7254
|
request.onerror = () => reject(request.error);
|
|
7958
7255
|
});
|
|
7959
7256
|
}
|
|
7960
|
-
async putInstance(
|
|
7257
|
+
async putInstance(instance2) {
|
|
7961
7258
|
if (!this.db) return;
|
|
7962
7259
|
return new Promise((resolve, reject) => {
|
|
7963
7260
|
const tx = this.db.transaction(INSTANCE_STORE_NAME, "readwrite");
|
|
7964
7261
|
const store = tx.objectStore(INSTANCE_STORE_NAME);
|
|
7965
|
-
store.put(
|
|
7262
|
+
store.put(instance2);
|
|
7966
7263
|
tx.oncomplete = () => resolve();
|
|
7967
7264
|
tx.onerror = () => reject(tx.error);
|
|
7968
7265
|
});
|
|
@@ -8109,10 +7406,382 @@ var BrowserPlayer = class {
|
|
|
8109
7406
|
}
|
|
8110
7407
|
}
|
|
8111
7408
|
};
|
|
7409
|
+
|
|
7410
|
+
// src/middleware-def.ts
|
|
7411
|
+
function defineMiddleware(def) {
|
|
7412
|
+
if (process.env.NODE_ENV !== "production") {
|
|
7413
|
+
if (!def.name || typeof def.name !== "string") {
|
|
7414
|
+
throw new Error("defineMiddleware: name is required and must be a string");
|
|
7415
|
+
}
|
|
7416
|
+
if (!def.match) {
|
|
7417
|
+
throw new Error("defineMiddleware: match pattern is required");
|
|
7418
|
+
}
|
|
7419
|
+
const patterns = Array.isArray(def.match) ? def.match : [def.match];
|
|
7420
|
+
for (const p of patterns) {
|
|
7421
|
+
if (typeof p !== "string") {
|
|
7422
|
+
throw new Error(`defineMiddleware: match pattern must be a string, got ${typeof p}`);
|
|
7423
|
+
}
|
|
7424
|
+
}
|
|
7425
|
+
if (def.priority !== void 0 && typeof def.priority !== "number") {
|
|
7426
|
+
throw new Error("defineMiddleware: priority must be a number");
|
|
7427
|
+
}
|
|
7428
|
+
if (!def.before && !def.after && !def.around) {
|
|
7429
|
+
throw new Error("defineMiddleware: at least one of before, after, or around must be provided");
|
|
7430
|
+
}
|
|
7431
|
+
}
|
|
7432
|
+
return def;
|
|
7433
|
+
}
|
|
7434
|
+
function extendMiddleware(base, overrides) {
|
|
7435
|
+
let introduce;
|
|
7436
|
+
if (base.introduce || overrides.introduce) {
|
|
7437
|
+
introduce = {
|
|
7438
|
+
fields: { ...base.introduce?.fields, ...overrides.introduce?.fields },
|
|
7439
|
+
states: { ...base.introduce?.states, ...overrides.introduce?.states },
|
|
7440
|
+
transitions: { ...base.introduce?.transitions, ...overrides.introduce?.transitions }
|
|
7441
|
+
};
|
|
7442
|
+
if (introduce.fields && Object.keys(introduce.fields).length === 0) introduce.fields = void 0;
|
|
7443
|
+
if (introduce.states && Object.keys(introduce.states).length === 0) introduce.states = void 0;
|
|
7444
|
+
if (introduce.transitions && Object.keys(introduce.transitions).length === 0) introduce.transitions = void 0;
|
|
7445
|
+
}
|
|
7446
|
+
const merged = {
|
|
7447
|
+
...base,
|
|
7448
|
+
...overrides,
|
|
7449
|
+
// Config is merged (overrides win per-key)
|
|
7450
|
+
config: base.config || overrides.config ? { ...base.config, ...overrides.config } : void 0
|
|
7451
|
+
};
|
|
7452
|
+
if (introduce) {
|
|
7453
|
+
merged.introduce = introduce;
|
|
7454
|
+
}
|
|
7455
|
+
if (process.env.NODE_ENV !== "production") {
|
|
7456
|
+
if (!merged.name || typeof merged.name !== "string") {
|
|
7457
|
+
throw new Error("extendMiddleware: resulting middleware must have a name");
|
|
7458
|
+
}
|
|
7459
|
+
if (!merged.match) {
|
|
7460
|
+
throw new Error("extendMiddleware: resulting middleware must have a match pattern");
|
|
7461
|
+
}
|
|
7462
|
+
if (!merged.before && !merged.after && !merged.around) {
|
|
7463
|
+
throw new Error("extendMiddleware: resulting middleware must have at least one of before, after, or around");
|
|
7464
|
+
}
|
|
7465
|
+
}
|
|
7466
|
+
return merged;
|
|
7467
|
+
}
|
|
7468
|
+
function withAuth(opts) {
|
|
7469
|
+
const _redirectTo = opts?.redirectTo;
|
|
7470
|
+
return {
|
|
7471
|
+
name: "mm:auth",
|
|
7472
|
+
match: "*:*:transition.execute",
|
|
7473
|
+
priority: 90,
|
|
7474
|
+
before(ctx) {
|
|
7475
|
+
if (!ctx.actor.id) {
|
|
7476
|
+
ctx.block(_redirectTo ? `redirect:${_redirectTo}` : "Authentication required");
|
|
7477
|
+
}
|
|
7478
|
+
}
|
|
7479
|
+
};
|
|
7480
|
+
}
|
|
7481
|
+
function withAuditLog(opts) {
|
|
7482
|
+
const _level = opts?.level ?? "info";
|
|
7483
|
+
return {
|
|
7484
|
+
name: "mm:audit-log",
|
|
7485
|
+
match: "*:*:transition.execute",
|
|
7486
|
+
priority: 0,
|
|
7487
|
+
after(ctx) {
|
|
7488
|
+
ctx.modify({
|
|
7489
|
+
__audit: {
|
|
7490
|
+
level: _level,
|
|
7491
|
+
actor: ctx.actor.id,
|
|
7492
|
+
transition: ctx.transition?.name,
|
|
7493
|
+
from: ctx.transition?.from,
|
|
7494
|
+
to: ctx.transition?.to,
|
|
7495
|
+
timestamp: ctx.timestamp
|
|
7496
|
+
}
|
|
7497
|
+
});
|
|
7498
|
+
}
|
|
7499
|
+
};
|
|
7500
|
+
}
|
|
7501
|
+
function withRateLimit(opts) {
|
|
7502
|
+
const _max = opts?.maxPerMinute ?? 60;
|
|
7503
|
+
return {
|
|
7504
|
+
name: "mm:rate-limit",
|
|
7505
|
+
match: "*:*:transition.execute",
|
|
7506
|
+
priority: 80,
|
|
7507
|
+
config: {
|
|
7508
|
+
maxPerMinute: { type: "number", default: _max }
|
|
7509
|
+
},
|
|
7510
|
+
before(ctx) {
|
|
7511
|
+
const fields = ctx.instance.fields;
|
|
7512
|
+
const counter = fields.__rateCounter || 0;
|
|
7513
|
+
if (counter >= _max) {
|
|
7514
|
+
ctx.block(`Rate limit exceeded: ${_max} per minute`);
|
|
7515
|
+
}
|
|
7516
|
+
}
|
|
7517
|
+
};
|
|
7518
|
+
}
|
|
7519
|
+
function withValidation(opts) {
|
|
7520
|
+
const _rules = opts?.rules ?? [];
|
|
7521
|
+
return {
|
|
7522
|
+
name: "mm:validation",
|
|
7523
|
+
match: "*:*:field.change",
|
|
7524
|
+
priority: 70,
|
|
7525
|
+
config: {
|
|
7526
|
+
rules: { type: "json", default: _rules }
|
|
7527
|
+
},
|
|
7528
|
+
before(ctx) {
|
|
7529
|
+
if (!ctx.field) return;
|
|
7530
|
+
for (const rule of _rules) {
|
|
7531
|
+
if (rule.fields.includes(ctx.field.name)) {
|
|
7532
|
+
ctx.block(rule.message);
|
|
7533
|
+
}
|
|
7534
|
+
}
|
|
7535
|
+
}
|
|
7536
|
+
};
|
|
7537
|
+
}
|
|
7538
|
+
function withMetrics(opts) {
|
|
7539
|
+
const _endpoint = opts?.endpoint;
|
|
7540
|
+
return {
|
|
7541
|
+
name: "mm:metrics",
|
|
7542
|
+
match: "*:*:*",
|
|
7543
|
+
priority: 100,
|
|
7544
|
+
config: {
|
|
7545
|
+
endpoint: { type: "string", default: _endpoint }
|
|
7546
|
+
},
|
|
7547
|
+
async around(ctx, next) {
|
|
7548
|
+
const start = ctx.timestamp;
|
|
7549
|
+
await next();
|
|
7550
|
+
const duration = Date.now() - start;
|
|
7551
|
+
ctx.modify({
|
|
7552
|
+
__metrics: {
|
|
7553
|
+
duration,
|
|
7554
|
+
endpoint: _endpoint,
|
|
7555
|
+
actor: ctx.actor.id
|
|
7556
|
+
}
|
|
7557
|
+
});
|
|
7558
|
+
}
|
|
7559
|
+
};
|
|
7560
|
+
}
|
|
7561
|
+
|
|
7562
|
+
// src/actor.ts
|
|
7563
|
+
function compileTimeOnly(name) {
|
|
7564
|
+
throw new Error(
|
|
7565
|
+
`${name}() is a compile-time function and cannot be called at runtime. Use \`mmrc build\` to compile your workflow.`
|
|
7566
|
+
);
|
|
7567
|
+
}
|
|
7568
|
+
var DEFAULT_SUPERVISION = {
|
|
7569
|
+
strategy: "escalate"
|
|
7570
|
+
};
|
|
7571
|
+
var DEFAULT_MAILBOX = {
|
|
7572
|
+
capacity: 1e3,
|
|
7573
|
+
overflow: "error",
|
|
7574
|
+
priority: "fifo"
|
|
7575
|
+
};
|
|
7576
|
+
function configureActor(config) {
|
|
7577
|
+
void config;
|
|
7578
|
+
return {
|
|
7579
|
+
__actor: true,
|
|
7580
|
+
supervision: config.supervision ?? DEFAULT_SUPERVISION,
|
|
7581
|
+
mailbox: config.mailbox ?? DEFAULT_MAILBOX,
|
|
7582
|
+
hierarchy: config.hierarchy ?? {}
|
|
7583
|
+
};
|
|
7584
|
+
}
|
|
7585
|
+
function spawnActor(_slug, _options) {
|
|
7586
|
+
compileTimeOnly("spawnActor");
|
|
7587
|
+
}
|
|
7588
|
+
function sendMessage(_instanceId, _action, _payload) {
|
|
7589
|
+
compileTimeOnly("sendMessage");
|
|
7590
|
+
}
|
|
7591
|
+
function isActorConfig(value) {
|
|
7592
|
+
return typeof value === "object" && value !== null && value.__actor === true;
|
|
7593
|
+
}
|
|
7594
|
+
|
|
7595
|
+
// src/constraints.ts
|
|
7596
|
+
var BUILT_IN_CONSTRAINTS = /* @__PURE__ */ new Set([
|
|
7597
|
+
"every state is reachable",
|
|
7598
|
+
"no deadlocks",
|
|
7599
|
+
"no unreachable states",
|
|
7600
|
+
"deterministic guards",
|
|
7601
|
+
"terminates",
|
|
7602
|
+
"no guard overlaps",
|
|
7603
|
+
"all roles defined",
|
|
7604
|
+
"all fields validated"
|
|
7605
|
+
]);
|
|
7606
|
+
function constraints(...rules) {
|
|
7607
|
+
if (process.env.NODE_ENV !== "production") {
|
|
7608
|
+
if (rules.length === 0) {
|
|
7609
|
+
throw new Error("constraints(): at least one constraint rule is required");
|
|
7610
|
+
}
|
|
7611
|
+
for (let i = 0; i < rules.length; i++) {
|
|
7612
|
+
const rule = rules[i];
|
|
7613
|
+
if (typeof rule !== "string" || rule.trim() === "") {
|
|
7614
|
+
throw new Error(
|
|
7615
|
+
`constraints(): rule at index ${i} must be a non-empty string, got ${typeof rule}`
|
|
7616
|
+
);
|
|
7617
|
+
}
|
|
7618
|
+
}
|
|
7619
|
+
}
|
|
7620
|
+
return {
|
|
7621
|
+
__constraints: true,
|
|
7622
|
+
rules: Object.freeze([...rules])
|
|
7623
|
+
};
|
|
7624
|
+
}
|
|
7625
|
+
function isConstraintDeclaration(value) {
|
|
7626
|
+
return typeof value === "object" && value !== null && value.__constraints === true && Array.isArray(value.rules);
|
|
7627
|
+
}
|
|
7628
|
+
function isBuiltInConstraint(rule) {
|
|
7629
|
+
return BUILT_IN_CONSTRAINTS.has(rule);
|
|
7630
|
+
}
|
|
7631
|
+
|
|
7632
|
+
// src/extend.ts
|
|
7633
|
+
function extend(base, options) {
|
|
7634
|
+
const _metadata = {
|
|
7635
|
+
__extend: true,
|
|
7636
|
+
base,
|
|
7637
|
+
options
|
|
7638
|
+
};
|
|
7639
|
+
throw new Error(
|
|
7640
|
+
`extend() is a compile-time declaration and cannot be called at runtime. Ensure your build pipeline includes the @mmapp/react-compiler Babel plugin or compile your workflow files with \`mmrc build\` before execution.
|
|
7641
|
+
|
|
7642
|
+
Base workflow: ${base?.name ?? "(anonymous)"}
|
|
7643
|
+
Derived slug: ${options.slug ?? "(not specified)"}`
|
|
7644
|
+
);
|
|
7645
|
+
return _metadata;
|
|
7646
|
+
}
|
|
7647
|
+
|
|
7648
|
+
// src/compose.ts
|
|
7649
|
+
function compose(workflow, ...mixins) {
|
|
7650
|
+
for (let i = 0; i < mixins.length; i++) {
|
|
7651
|
+
const mixin = mixins[i];
|
|
7652
|
+
if (!mixin || mixin.__mixin !== true) {
|
|
7653
|
+
throw new Error(
|
|
7654
|
+
`compose() argument ${i + 2} is not a valid WorkflowMixin. Each mixin must be created by a mixin factory (e.g. withAuditTrail(), withSoftDelete()). Received: ${typeof mixin === "object" ? JSON.stringify(mixin) : String(mixin)}`
|
|
7655
|
+
);
|
|
7656
|
+
}
|
|
7657
|
+
}
|
|
7658
|
+
const metadata = {
|
|
7659
|
+
__composed: true,
|
|
7660
|
+
workflow,
|
|
7661
|
+
mixins: Object.freeze([...mixins])
|
|
7662
|
+
};
|
|
7663
|
+
const composed = (async (...args) => {
|
|
7664
|
+
return workflow(...args);
|
|
7665
|
+
});
|
|
7666
|
+
Object.defineProperty(composed, "__composed", {
|
|
7667
|
+
value: metadata,
|
|
7668
|
+
writable: false,
|
|
7669
|
+
enumerable: false,
|
|
7670
|
+
configurable: false
|
|
7671
|
+
});
|
|
7672
|
+
Object.defineProperty(composed, "name", {
|
|
7673
|
+
value: `composed(${workflow.name || "anonymous"})`,
|
|
7674
|
+
writable: false,
|
|
7675
|
+
configurable: true
|
|
7676
|
+
});
|
|
7677
|
+
return composed;
|
|
7678
|
+
}
|
|
7679
|
+
|
|
7680
|
+
// src/imperative.ts
|
|
7681
|
+
function compileTimeOnly2(name) {
|
|
7682
|
+
throw new Error(
|
|
7683
|
+
`${name}() is a compile-time function and cannot be called at runtime. Use \`mmrc build\` to compile your workflow.`
|
|
7684
|
+
);
|
|
7685
|
+
}
|
|
7686
|
+
function compileTimeProxy(label) {
|
|
7687
|
+
return new Proxy(
|
|
7688
|
+
{},
|
|
7689
|
+
{
|
|
7690
|
+
get(_target, prop) {
|
|
7691
|
+
throw new Error(
|
|
7692
|
+
`Cannot access \`${label}.${String(prop)}\` at runtime. \`${label}\` is a compile-time constant. Use \`mmrc build\` to compile your workflow.`
|
|
7693
|
+
);
|
|
7694
|
+
}
|
|
7695
|
+
}
|
|
7696
|
+
);
|
|
7697
|
+
}
|
|
7698
|
+
function validate(_condition, _message, _severity) {
|
|
7699
|
+
compileTimeOnly2("validate");
|
|
7700
|
+
}
|
|
7701
|
+
function log(_event, _data) {
|
|
7702
|
+
compileTimeOnly2("log");
|
|
7703
|
+
}
|
|
7704
|
+
function notify2(_to, _message, _opts) {
|
|
7705
|
+
compileTimeOnly2("notify");
|
|
7706
|
+
}
|
|
7707
|
+
function emit(_event, _payload) {
|
|
7708
|
+
compileTimeOnly2("emit");
|
|
7709
|
+
}
|
|
7710
|
+
function requireRole2(..._roles) {
|
|
7711
|
+
compileTimeOnly2("requireRole");
|
|
7712
|
+
}
|
|
7713
|
+
function requireField(..._fields) {
|
|
7714
|
+
compileTimeOnly2("requireField");
|
|
7715
|
+
}
|
|
7716
|
+
function guard(_expression) {
|
|
7717
|
+
compileTimeOnly2("guard");
|
|
7718
|
+
}
|
|
7719
|
+
function every(_interval, _fn) {
|
|
7720
|
+
compileTimeOnly2("every");
|
|
7721
|
+
}
|
|
7722
|
+
function cron2(_expression, _fn) {
|
|
7723
|
+
compileTimeOnly2("cron");
|
|
7724
|
+
}
|
|
7725
|
+
function after(_delay, _fn) {
|
|
7726
|
+
compileTimeOnly2("after");
|
|
7727
|
+
}
|
|
7728
|
+
function on(_pattern, _handlerOrOpts) {
|
|
7729
|
+
compileTimeOnly2("on");
|
|
7730
|
+
}
|
|
7731
|
+
function timeout(_duration, _handler) {
|
|
7732
|
+
compileTimeOnly2("timeout");
|
|
7733
|
+
}
|
|
7734
|
+
function userAction(_name, _opts) {
|
|
7735
|
+
compileTimeOnly2("userAction");
|
|
7736
|
+
}
|
|
7737
|
+
function userChoice(_options) {
|
|
7738
|
+
compileTimeOnly2("userChoice");
|
|
7739
|
+
}
|
|
7740
|
+
function named(_name, _stateCall) {
|
|
7741
|
+
compileTimeOnly2("named");
|
|
7742
|
+
}
|
|
7743
|
+
function delay(_duration) {
|
|
7744
|
+
compileTimeOnly2("delay");
|
|
7745
|
+
}
|
|
7746
|
+
function allowTransition(_name, _opts) {
|
|
7747
|
+
compileTimeOnly2("allowTransition");
|
|
7748
|
+
}
|
|
7749
|
+
function restrict(_field, _opts) {
|
|
7750
|
+
compileTimeOnly2("restrict");
|
|
7751
|
+
}
|
|
7752
|
+
function visibleTo(..._roles) {
|
|
7753
|
+
compileTimeOnly2("visibleTo");
|
|
7754
|
+
}
|
|
7755
|
+
function editableBy(..._roles) {
|
|
7756
|
+
compileTimeOnly2("editableBy");
|
|
7757
|
+
}
|
|
7758
|
+
function editableIn(..._states) {
|
|
7759
|
+
compileTimeOnly2("editableIn");
|
|
7760
|
+
}
|
|
7761
|
+
function defineRoles(roles) {
|
|
7762
|
+
void roles;
|
|
7763
|
+
compileTimeOnly2("defineRoles");
|
|
7764
|
+
}
|
|
7765
|
+
function runtime(_target) {
|
|
7766
|
+
compileTimeOnly2("runtime");
|
|
7767
|
+
}
|
|
7768
|
+
function orchestration(config) {
|
|
7769
|
+
void config;
|
|
7770
|
+
compileTimeOnly2("orchestration");
|
|
7771
|
+
}
|
|
7772
|
+
function blueprint(_slug, _config) {
|
|
7773
|
+
compileTimeOnly2("blueprint");
|
|
7774
|
+
}
|
|
7775
|
+
function patch(_id, _overrides) {
|
|
7776
|
+
compileTimeOnly2("patch");
|
|
7777
|
+
}
|
|
7778
|
+
var actor = compileTimeProxy("actor");
|
|
7779
|
+
var instance = compileTimeProxy("instance");
|
|
8112
7780
|
// Annotate the CommonJS export names for ESM import in node:
|
|
8113
7781
|
0 && (module.exports = {
|
|
8114
7782
|
Accordion,
|
|
8115
7783
|
AnimatedBox,
|
|
7784
|
+
BUILT_IN_CONSTRAINTS,
|
|
8116
7785
|
Badge,
|
|
8117
7786
|
Blueprint,
|
|
8118
7787
|
BrowserPlayer,
|
|
@@ -8139,6 +7808,7 @@ var BrowserPlayer = class {
|
|
|
8139
7808
|
Modal,
|
|
8140
7809
|
ModelBuilder,
|
|
8141
7810
|
NavLink,
|
|
7811
|
+
ORCHESTRATION_PRESETS,
|
|
8142
7812
|
PlayerProvider,
|
|
8143
7813
|
RoleGuard,
|
|
8144
7814
|
Route,
|
|
@@ -8162,12 +7832,19 @@ var BrowserPlayer = class {
|
|
|
8162
7832
|
WorkflowProvider,
|
|
8163
7833
|
WorkflowRuntime,
|
|
8164
7834
|
action,
|
|
7835
|
+
actor,
|
|
7836
|
+
after,
|
|
7837
|
+
allowTransition,
|
|
8165
7838
|
and,
|
|
8166
7839
|
applyMixins,
|
|
8167
7840
|
approval,
|
|
8168
7841
|
assertModelValid,
|
|
8169
7842
|
cedar,
|
|
7843
|
+
compose,
|
|
7844
|
+
computeVisibility,
|
|
7845
|
+
configureActor,
|
|
8170
7846
|
connector,
|
|
7847
|
+
constraints,
|
|
8171
7848
|
createActions,
|
|
8172
7849
|
createCRUD,
|
|
8173
7850
|
createLocalDataResolver,
|
|
@@ -8176,16 +7853,26 @@ var BrowserPlayer = class {
|
|
|
8176
7853
|
cron,
|
|
8177
7854
|
crud,
|
|
8178
7855
|
defineBlueprint,
|
|
7856
|
+
defineImperativeBlueprint,
|
|
7857
|
+
defineMiddleware,
|
|
8179
7858
|
defineModel,
|
|
8180
7859
|
defineModule,
|
|
7860
|
+
defineRoles,
|
|
8181
7861
|
defineWorkspace,
|
|
7862
|
+
delay,
|
|
8182
7863
|
deriveInstanceKey,
|
|
8183
7864
|
deriveInstanceKeySync,
|
|
8184
7865
|
describeModel,
|
|
8185
7866
|
deviceAction,
|
|
8186
7867
|
dmn,
|
|
7868
|
+
editableBy,
|
|
7869
|
+
editableIn,
|
|
7870
|
+
emit,
|
|
8187
7871
|
escalation,
|
|
7872
|
+
every,
|
|
8188
7873
|
expr,
|
|
7874
|
+
extend,
|
|
7875
|
+
extendMiddleware,
|
|
8189
7876
|
field,
|
|
8190
7877
|
fieldContains,
|
|
8191
7878
|
fieldEquals,
|
|
@@ -8200,12 +7887,21 @@ var BrowserPlayer = class {
|
|
|
8200
7887
|
getInstalledModule,
|
|
8201
7888
|
getInstalledModules,
|
|
8202
7889
|
graphql,
|
|
7890
|
+
guard,
|
|
8203
7891
|
hasAnyRole,
|
|
8204
7892
|
hasRole,
|
|
7893
|
+
imperativeCron,
|
|
7894
|
+
imperativeLog,
|
|
7895
|
+
imperativeNotify,
|
|
7896
|
+
imperativeRequireRole,
|
|
8205
7897
|
inState,
|
|
8206
7898
|
inputEquals,
|
|
8207
7899
|
inputRequired,
|
|
7900
|
+
instance,
|
|
8208
7901
|
isActor,
|
|
7902
|
+
isActorConfig,
|
|
7903
|
+
isBuiltInConstraint,
|
|
7904
|
+
isConstraintDeclaration,
|
|
8209
7905
|
isCreator,
|
|
8210
7906
|
isOwner,
|
|
8211
7907
|
isPlayerDebug,
|
|
@@ -8215,19 +7911,28 @@ var BrowserPlayer = class {
|
|
|
8215
7911
|
loadExperienceWorkflow,
|
|
8216
7912
|
logEvent,
|
|
8217
7913
|
model,
|
|
7914
|
+
named,
|
|
8218
7915
|
normalizeDefinition,
|
|
8219
7916
|
not,
|
|
8220
7917
|
notInState,
|
|
8221
7918
|
notify,
|
|
7919
|
+
on,
|
|
8222
7920
|
or,
|
|
7921
|
+
orchestration,
|
|
7922
|
+
patch,
|
|
8223
7923
|
pipe,
|
|
8224
7924
|
playerLog,
|
|
8225
7925
|
prefetchData,
|
|
8226
7926
|
refHasAnyRole,
|
|
8227
7927
|
refHasRole,
|
|
8228
7928
|
requireAuth,
|
|
7929
|
+
requireField,
|
|
8229
7930
|
requireRole,
|
|
7931
|
+
resolveOrchestration,
|
|
7932
|
+
restrict,
|
|
8230
7933
|
review,
|
|
7934
|
+
runtime,
|
|
7935
|
+
sendMessage,
|
|
8231
7936
|
serverAction,
|
|
8232
7937
|
setAuthResolver,
|
|
8233
7938
|
setChannelTransport,
|
|
@@ -8247,10 +7952,12 @@ var BrowserPlayer = class {
|
|
|
8247
7952
|
setServerStateResolver,
|
|
8248
7953
|
setViewResolver,
|
|
8249
7954
|
spawn,
|
|
7955
|
+
spawnActor,
|
|
8250
7956
|
sql,
|
|
8251
7957
|
state,
|
|
8252
7958
|
syncConfigDefaults,
|
|
8253
7959
|
testModel,
|
|
7960
|
+
timeout,
|
|
8254
7961
|
transition,
|
|
8255
7962
|
updateDefinitionConfig,
|
|
8256
7963
|
useAuth,
|
|
@@ -8283,6 +7990,7 @@ var BrowserPlayer = class {
|
|
|
8283
7990
|
usePlayer,
|
|
8284
7991
|
usePlayerContext,
|
|
8285
7992
|
usePlayerContextSafe,
|
|
7993
|
+
usePresence,
|
|
8286
7994
|
useQuery,
|
|
8287
7995
|
useRealtimeQuery,
|
|
8288
7996
|
useRole,
|
|
@@ -8295,20 +8003,30 @@ var BrowserPlayer = class {
|
|
|
8295
8003
|
useToast,
|
|
8296
8004
|
useTransition,
|
|
8297
8005
|
useView,
|
|
8006
|
+
useVisibility,
|
|
8298
8007
|
useWhileIn,
|
|
8299
8008
|
useWorkflow,
|
|
8300
8009
|
useWorkflowState,
|
|
8010
|
+
userAction,
|
|
8011
|
+
userChoice,
|
|
8012
|
+
validate,
|
|
8301
8013
|
validateExperienceWorkflow,
|
|
8302
8014
|
validateModel,
|
|
8015
|
+
visibleTo,
|
|
8303
8016
|
when,
|
|
8017
|
+
withAuditLog,
|
|
8304
8018
|
withAuditTrail,
|
|
8019
|
+
withAuth,
|
|
8020
|
+
withMetrics,
|
|
8305
8021
|
withOwnership,
|
|
8306
8022
|
withPagination,
|
|
8307
8023
|
withRBAC,
|
|
8024
|
+
withRateLimit,
|
|
8308
8025
|
withSearch,
|
|
8309
8026
|
withSlug,
|
|
8310
8027
|
withSoftDelete,
|
|
8311
8028
|
withTags,
|
|
8312
8029
|
withTimestamps,
|
|
8030
|
+
withValidation,
|
|
8313
8031
|
withVersioning
|
|
8314
8032
|
});
|