slapflow 1.0.2 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -1
- package/SPEC-RU.md +104 -36
- package/SPEC.md +104 -36
- package/dist/index.cjs +314 -63
- package/dist/index.d.cts +38 -8
- package/dist/index.d.ts +38 -8
- package/dist/index.js +309 -61
- package/package.json +12 -2
package/dist/index.cjs
CHANGED
|
@@ -20,14 +20,17 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/index.ts
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
|
+
BUILTIN_ACTIONS: () => BUILTIN_ACTIONS,
|
|
24
|
+
BUILTIN_ACTION_NAMES: () => BUILTIN_ACTION_NAMES,
|
|
25
|
+
BUILTIN_CONDITIONS: () => BUILTIN_CONDITIONS,
|
|
26
|
+
BUILTIN_CONDITION_NAMES: () => BUILTIN_CONDITION_NAMES,
|
|
23
27
|
PubSub: () => PubSub,
|
|
24
28
|
catchError: () => catchError,
|
|
25
|
-
createActionsRegistry: () => createActionsRegistry,
|
|
26
|
-
createConditionsRegistry: () => createConditionsRegistry,
|
|
27
29
|
createFlow: () => createFlow,
|
|
28
30
|
createMemoryTraceSink: () => createMemoryTraceSink,
|
|
29
31
|
createPubSub: () => createPubSub,
|
|
30
32
|
createWS: () => createWS,
|
|
33
|
+
createWebSocket: () => createWebSocket,
|
|
31
34
|
defineConfig: () => defineConfig,
|
|
32
35
|
defineErrorReporter: () => defineErrorReporter
|
|
33
36
|
});
|
|
@@ -36,9 +39,6 @@ module.exports = __toCommonJS(index_exports);
|
|
|
36
39
|
// src/helpers/config/defineConfig.ts
|
|
37
40
|
var defineConfig = (config) => config;
|
|
38
41
|
|
|
39
|
-
// src/helpers/trace/cloneData.ts
|
|
40
|
-
var cloneData = (data) => ({ ...data });
|
|
41
|
-
|
|
42
42
|
// src/helpers/trace/createMemoryTraceSink.ts
|
|
43
43
|
var createMemoryTraceSink = () => {
|
|
44
44
|
const items = [];
|
|
@@ -50,22 +50,9 @@ var createMemoryTraceSink = () => {
|
|
|
50
50
|
};
|
|
51
51
|
};
|
|
52
52
|
|
|
53
|
-
// src/helpers/errors/slapError.ts
|
|
54
|
-
var slapError = (code, message, extras = {}) => ({ code, message, ...extras });
|
|
55
|
-
|
|
56
53
|
// src/helpers/errors/defineErrorReporter.ts
|
|
57
54
|
var defineErrorReporter = (handlers) => typeof handlers === "function" ? handlers : handlers.report;
|
|
58
55
|
|
|
59
|
-
// src/errors.ts
|
|
60
|
-
var SyncAsyncError = class extends Error {
|
|
61
|
-
slapError;
|
|
62
|
-
constructor(error) {
|
|
63
|
-
super(error.message);
|
|
64
|
-
this.name = "SyncAsyncError";
|
|
65
|
-
this.slapError = error;
|
|
66
|
-
}
|
|
67
|
-
};
|
|
68
|
-
|
|
69
56
|
// src/helpers/ids/createId.ts
|
|
70
57
|
var alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
|
71
58
|
var idLength = 12;
|
|
@@ -87,14 +74,35 @@ var isBusEvent = (event) => {
|
|
|
87
74
|
return typeof candidate.id === "string" && typeof candidate.topic === "string" && typeof candidate.occurredAt === "number" && typeof candidate.serialized === "string" && "parsed" in candidate && (candidate.origin === void 0 || typeof candidate.origin === "string");
|
|
88
75
|
};
|
|
89
76
|
|
|
77
|
+
// src/helpers/pubSub/matchesTopic.ts
|
|
78
|
+
var matchesTopic = (topic, pattern) => {
|
|
79
|
+
if (!pattern.includes("*")) {
|
|
80
|
+
return topic === pattern;
|
|
81
|
+
}
|
|
82
|
+
const topicParts = topic.split(".");
|
|
83
|
+
const patternParts = pattern.split(".");
|
|
84
|
+
if (topicParts.length !== patternParts.length) {
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
return patternParts.every((part, index) => part === "*" || part === topicParts[index]);
|
|
88
|
+
};
|
|
89
|
+
|
|
90
90
|
// src/helpers/pubSub/serializeError.ts
|
|
91
91
|
var serializeError = (error) => ({
|
|
92
92
|
error: error instanceof Error ? error.message : String(error)
|
|
93
93
|
});
|
|
94
94
|
|
|
95
|
-
// src/
|
|
95
|
+
// src/createPubSub.ts
|
|
96
96
|
var createPubSub = (options = {}) => {
|
|
97
97
|
const subscribers = /* @__PURE__ */ new Map();
|
|
98
|
+
const wildcardSubscribers = /* @__PURE__ */ new Map();
|
|
99
|
+
const runHandler = (event, handler) => {
|
|
100
|
+
try {
|
|
101
|
+
handler(event);
|
|
102
|
+
} catch (error) {
|
|
103
|
+
options.onError?.({ type: "subscriber", event, error });
|
|
104
|
+
}
|
|
105
|
+
};
|
|
98
106
|
const dispatch = (event) => {
|
|
99
107
|
let dispatchedEvent;
|
|
100
108
|
if (!isBusEvent(event)) {
|
|
@@ -108,10 +116,13 @@ var createPubSub = (options = {}) => {
|
|
|
108
116
|
const handlers = subscribers.get(event.topic);
|
|
109
117
|
if (handlers) {
|
|
110
118
|
for (const handler of [...handlers]) {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
119
|
+
runHandler(event, handler);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
for (const [pattern, wildcardHandlers] of wildcardSubscribers) {
|
|
123
|
+
if (matchesTopic(event.topic, pattern)) {
|
|
124
|
+
for (const handler of [...wildcardHandlers]) {
|
|
125
|
+
runHandler(event, handler);
|
|
115
126
|
}
|
|
116
127
|
}
|
|
117
128
|
}
|
|
@@ -120,23 +131,24 @@ var createPubSub = (options = {}) => {
|
|
|
120
131
|
return dispatchedEvent;
|
|
121
132
|
};
|
|
122
133
|
const on = (event, handler) => {
|
|
123
|
-
const
|
|
124
|
-
const
|
|
125
|
-
handlers.add(
|
|
126
|
-
|
|
134
|
+
const registry = event.includes("*") ? wildcardSubscribers : subscribers;
|
|
135
|
+
const handlers = registry.get(event) ?? /* @__PURE__ */ new Set();
|
|
136
|
+
handlers.add(handler);
|
|
137
|
+
registry.set(event, handlers);
|
|
127
138
|
return () => off(event, handler);
|
|
128
139
|
};
|
|
129
140
|
const off = (event, handler) => {
|
|
141
|
+
const registry = event.includes("*") ? wildcardSubscribers : subscribers;
|
|
130
142
|
if (handler) {
|
|
131
|
-
const handlers =
|
|
143
|
+
const handlers = registry.get(event);
|
|
132
144
|
if (handlers) {
|
|
133
145
|
handlers.delete(handler);
|
|
134
146
|
if (handlers.size === 0) {
|
|
135
|
-
|
|
147
|
+
registry.delete(event);
|
|
136
148
|
}
|
|
137
149
|
}
|
|
138
150
|
} else {
|
|
139
|
-
|
|
151
|
+
registry.delete(event);
|
|
140
152
|
}
|
|
141
153
|
};
|
|
142
154
|
const emit = (topic, payload, emitOptions = {}) => {
|
|
@@ -178,6 +190,16 @@ var createPubSub = (options = {}) => {
|
|
|
178
190
|
};
|
|
179
191
|
var PubSub = createPubSub();
|
|
180
192
|
|
|
193
|
+
// src/helpers/errors/syncAsyncError.ts
|
|
194
|
+
var SyncAsyncError = class extends Error {
|
|
195
|
+
slapError;
|
|
196
|
+
constructor(error) {
|
|
197
|
+
super(error.message);
|
|
198
|
+
this.name = "SyncAsyncError";
|
|
199
|
+
this.slapError = error;
|
|
200
|
+
}
|
|
201
|
+
};
|
|
202
|
+
|
|
181
203
|
// src/helpers/actions/coreDelay.ts
|
|
182
204
|
var coreDelay = async ({
|
|
183
205
|
props,
|
|
@@ -214,10 +236,7 @@ var coreEmit = ({
|
|
|
214
236
|
};
|
|
215
237
|
|
|
216
238
|
// src/helpers/actions/coreFail.ts
|
|
217
|
-
var coreFail = ({
|
|
218
|
-
props,
|
|
219
|
-
runtime
|
|
220
|
-
}) => runtime.fail(String(props.reason ?? "failed"), props.data);
|
|
239
|
+
var coreFail = ({ props, runtime }) => runtime.fail(String(props.reason ?? "failed"), props.data);
|
|
221
240
|
|
|
222
241
|
// src/helpers/retry/getRetryDelay.ts
|
|
223
242
|
var getRetryDelay = (attempt, options) => {
|
|
@@ -424,10 +443,7 @@ var corePatch = ({
|
|
|
424
443
|
};
|
|
425
444
|
|
|
426
445
|
// src/helpers/actions/coreSet.ts
|
|
427
|
-
var coreSet = ({
|
|
428
|
-
props,
|
|
429
|
-
runtime
|
|
430
|
-
}) => {
|
|
446
|
+
var coreSet = ({ props, runtime }) => {
|
|
431
447
|
const path = props.path;
|
|
432
448
|
if (typeof path === "string") {
|
|
433
449
|
runtime.set(path, props.value);
|
|
@@ -448,13 +464,10 @@ var coreSetData = ({
|
|
|
448
464
|
};
|
|
449
465
|
|
|
450
466
|
// src/helpers/actions/coreStop.ts
|
|
451
|
-
var coreStop = ({
|
|
452
|
-
props,
|
|
453
|
-
runtime
|
|
454
|
-
}) => runtime.stop(String(props.reason ?? "stopped"));
|
|
467
|
+
var coreStop = ({ props, runtime }) => runtime.stop(String(props.reason ?? "stopped"));
|
|
455
468
|
|
|
456
|
-
// src/
|
|
457
|
-
var
|
|
469
|
+
// src/helpers/actions/index.ts
|
|
470
|
+
var BUILTIN_ACTIONS = [
|
|
458
471
|
["core.noop", coreNoop],
|
|
459
472
|
["core.stop", coreStop],
|
|
460
473
|
["core.fail", coreFail],
|
|
@@ -468,7 +481,8 @@ var createActionsRegistry = () => /* @__PURE__ */ new Map([
|
|
|
468
481
|
["core.emit", coreEmit],
|
|
469
482
|
["core.patch", corePatch],
|
|
470
483
|
["core.delay", coreDelay]
|
|
471
|
-
]
|
|
484
|
+
];
|
|
485
|
+
var BUILTIN_ACTION_NAMES = new Set(BUILTIN_ACTIONS.map(([name]) => name));
|
|
472
486
|
|
|
473
487
|
// src/helpers/conditions/changedCondition.ts
|
|
474
488
|
var changedCondition = (_args, current, previous) => !Object.is(current, previous);
|
|
@@ -562,8 +576,8 @@ var typeIsCondition = (_args, value, expected) => {
|
|
|
562
576
|
return expected === "string" || expected === "number" || expected === "boolean" ? typeof value === expected : false;
|
|
563
577
|
};
|
|
564
578
|
|
|
565
|
-
// src/
|
|
566
|
-
var
|
|
579
|
+
// src/helpers/conditions/index.ts
|
|
580
|
+
var BUILTIN_CONDITIONS = [
|
|
567
581
|
["eq", eqCondition],
|
|
568
582
|
["neq", neqCondition],
|
|
569
583
|
["gt", gtCondition],
|
|
@@ -580,7 +594,8 @@ var createConditionsRegistry = () => /* @__PURE__ */ new Map([
|
|
|
580
594
|
["typeIs", typeIsCondition],
|
|
581
595
|
["changed", changedCondition],
|
|
582
596
|
["cooldownReady", cooldownReadyCondition]
|
|
583
|
-
]
|
|
597
|
+
];
|
|
598
|
+
var BUILTIN_CONDITION_NAMES = new Set(BUILTIN_CONDITIONS.map(([name]) => name));
|
|
584
599
|
|
|
585
600
|
// src/helpers/runner/applyResult.ts
|
|
586
601
|
var applyResult = (result, state, mergeData) => {
|
|
@@ -594,6 +609,9 @@ var applyResult = (result, state, mergeData) => {
|
|
|
594
609
|
state.events.push(...result.events);
|
|
595
610
|
};
|
|
596
611
|
|
|
612
|
+
// src/helpers/errors/slapError.ts
|
|
613
|
+
var slapError = (code, message, extras = {}) => ({ code, message, ...extras });
|
|
614
|
+
|
|
597
615
|
// src/helpers/path/resolveValue.ts
|
|
598
616
|
var import_objwalk3 = require("objwalk");
|
|
599
617
|
|
|
@@ -1032,7 +1050,7 @@ var executeNext = (item, depth, state, environment) => {
|
|
|
1032
1050
|
const id = typeof item === "string" ? item : item.strategy;
|
|
1033
1051
|
if (typeof item !== "string" && item.when) {
|
|
1034
1052
|
const runtime = createRuntime(state);
|
|
1035
|
-
const condition = evaluateCondition(item.when, environment.
|
|
1053
|
+
const condition = evaluateCondition(item.when, environment.registry.conditions, { ...state, runtime, strategy: id });
|
|
1036
1054
|
if (!condition.ok) {
|
|
1037
1055
|
return { status: "failed", error: condition.error, patches: [], events: [] };
|
|
1038
1056
|
}
|
|
@@ -1284,6 +1302,9 @@ var normalizeActionResult = (raw) => {
|
|
|
1284
1302
|
};
|
|
1285
1303
|
};
|
|
1286
1304
|
|
|
1305
|
+
// src/helpers/trace/cloneData.ts
|
|
1306
|
+
var cloneData = (data) => ({ ...data });
|
|
1307
|
+
|
|
1287
1308
|
// src/helpers/runner/pushTrace.ts
|
|
1288
1309
|
var pushTrace = (state, step, depth, strategyId, strategy, status, props, dataBefore, startedAt, reason) => {
|
|
1289
1310
|
state.traceSink?.push({
|
|
@@ -1466,7 +1487,7 @@ var executeStrategy = (id, extraProps, depth, state, environment) => {
|
|
|
1466
1487
|
events: []
|
|
1467
1488
|
};
|
|
1468
1489
|
}
|
|
1469
|
-
const action = environment.
|
|
1490
|
+
const action = environment.registry.actions.get(strategy.fn);
|
|
1470
1491
|
if (!action) {
|
|
1471
1492
|
return {
|
|
1472
1493
|
status: "failed",
|
|
@@ -1521,7 +1542,7 @@ var executeStrategy = (id, extraProps, depth, state, environment) => {
|
|
|
1521
1542
|
const dataBefore = cloneData(state.data);
|
|
1522
1543
|
const traceStep = state.stepCounter.current + 1;
|
|
1523
1544
|
const startedAt = Date.now();
|
|
1524
|
-
const condition = evaluateCondition(strategy.when, environment.
|
|
1545
|
+
const condition = evaluateCondition(strategy.when, environment.registry.conditions, {
|
|
1525
1546
|
...state,
|
|
1526
1547
|
runtime,
|
|
1527
1548
|
strategy: id
|
|
@@ -1833,6 +1854,17 @@ var validateCondition = (expression, strategy, path, conditionsRegistry, errors)
|
|
|
1833
1854
|
return;
|
|
1834
1855
|
}
|
|
1835
1856
|
const [operator, ...args] = expression;
|
|
1857
|
+
if (operator === "guard") {
|
|
1858
|
+
if (args.length !== 1 || typeof args[0] !== "string") {
|
|
1859
|
+
errors.push({
|
|
1860
|
+
code: "CONDITION_INVALID",
|
|
1861
|
+
message: "Guard reference must be a single string name",
|
|
1862
|
+
strategy,
|
|
1863
|
+
path
|
|
1864
|
+
});
|
|
1865
|
+
}
|
|
1866
|
+
return;
|
|
1867
|
+
}
|
|
1836
1868
|
if (operator === "and" || operator === "or") {
|
|
1837
1869
|
args.forEach((arg, index) => validateCondition(arg, strategy, `${path}.${index + 1}`, conditionsRegistry, errors));
|
|
1838
1870
|
return;
|
|
@@ -1878,6 +1910,82 @@ var validateNextList = (config, list, path, strategy, conditionsRegistry, errors
|
|
|
1878
1910
|
});
|
|
1879
1911
|
};
|
|
1880
1912
|
|
|
1913
|
+
// src/helpers/validation/resolveGuards.ts
|
|
1914
|
+
var isGuardRef = (expression) => Array.isArray(expression) && expression.length === 2 && expression[0] === "guard" && typeof expression[1] === "string";
|
|
1915
|
+
var resolveRef = (config, name, visiting, path) => {
|
|
1916
|
+
if (visiting.includes(name)) {
|
|
1917
|
+
return {
|
|
1918
|
+
issue: { code: "GUARD_CYCLE", message: `Guard "${name}" is part of a reference cycle`, guard: name, path }
|
|
1919
|
+
};
|
|
1920
|
+
}
|
|
1921
|
+
const guard = config.guards?.[name];
|
|
1922
|
+
if (guard === void 0) {
|
|
1923
|
+
return { issue: { code: "GUARD_NOT_FOUND", message: `Guard "${name}" is not defined`, guard: name, path } };
|
|
1924
|
+
}
|
|
1925
|
+
return resolveExpression(config, guard, [...visiting, name], path);
|
|
1926
|
+
};
|
|
1927
|
+
var resolveExpression = (config, expression, visiting, path) => {
|
|
1928
|
+
if (isGuardRef(expression)) {
|
|
1929
|
+
return resolveRef(config, expression[1], visiting, path);
|
|
1930
|
+
}
|
|
1931
|
+
if (!Array.isArray(expression) || typeof expression[0] !== "string") {
|
|
1932
|
+
return { expression };
|
|
1933
|
+
}
|
|
1934
|
+
const [operator, ...args] = expression;
|
|
1935
|
+
if (operator === "and" || operator === "or") {
|
|
1936
|
+
const resolved = [];
|
|
1937
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
1938
|
+
const result = resolveExpression(config, args[index], visiting, `${path}.${index + 1}`);
|
|
1939
|
+
if (result.issue) {
|
|
1940
|
+
return result;
|
|
1941
|
+
}
|
|
1942
|
+
resolved.push(result.expression);
|
|
1943
|
+
}
|
|
1944
|
+
return { expression: [operator, ...resolved] };
|
|
1945
|
+
}
|
|
1946
|
+
if (operator === "not") {
|
|
1947
|
+
const result = resolveExpression(config, args[0], visiting, `${path}.1`);
|
|
1948
|
+
if (result.issue) {
|
|
1949
|
+
return result;
|
|
1950
|
+
}
|
|
1951
|
+
return { expression: ["not", result.expression] };
|
|
1952
|
+
}
|
|
1953
|
+
return { expression };
|
|
1954
|
+
};
|
|
1955
|
+
var resolveGuards = (config) => {
|
|
1956
|
+
const issues = [];
|
|
1957
|
+
const resolveWhen = (when, path) => {
|
|
1958
|
+
if (when === void 0) {
|
|
1959
|
+
return void 0;
|
|
1960
|
+
}
|
|
1961
|
+
const result = resolveExpression(config, when, [], path);
|
|
1962
|
+
if (result.issue) {
|
|
1963
|
+
issues.push(result.issue);
|
|
1964
|
+
return when;
|
|
1965
|
+
}
|
|
1966
|
+
return result.expression;
|
|
1967
|
+
};
|
|
1968
|
+
const resolveNext = (next, prefix) => next.map((item, index) => {
|
|
1969
|
+
if (typeof item === "string" || !item || typeof item !== "object" || item.when === void 0) {
|
|
1970
|
+
return item;
|
|
1971
|
+
}
|
|
1972
|
+
const target = item;
|
|
1973
|
+
const when = resolveWhen(target.when, `${prefix}.${index}.when`);
|
|
1974
|
+
return when === void 0 ? item : { ...target, when };
|
|
1975
|
+
});
|
|
1976
|
+
const strategies = {};
|
|
1977
|
+
for (const [id, strategy] of Object.entries(config.strategies)) {
|
|
1978
|
+
const when = strategy.when === void 0 ? void 0 : resolveWhen(strategy.when, `${id}.when`);
|
|
1979
|
+
strategies[id] = {
|
|
1980
|
+
...strategy,
|
|
1981
|
+
...when !== void 0 ? { when } : {},
|
|
1982
|
+
...strategy.then ? { then: resolveNext(strategy.then, `${id}.then`) } : {},
|
|
1983
|
+
...strategy.catch ? { catch: resolveNext(strategy.catch, `${id}.catch`) } : {}
|
|
1984
|
+
};
|
|
1985
|
+
}
|
|
1986
|
+
return { config: { ...config, strategies }, issues };
|
|
1987
|
+
};
|
|
1988
|
+
|
|
1881
1989
|
// src/helpers/validation/validateConfig.ts
|
|
1882
1990
|
var validateConfig = (config, actionsRegistry, conditionsRegistry) => {
|
|
1883
1991
|
const errors = [];
|
|
@@ -1896,6 +2004,22 @@ var validateConfig = (config, actionsRegistry, conditionsRegistry) => {
|
|
|
1896
2004
|
warnings
|
|
1897
2005
|
};
|
|
1898
2006
|
}
|
|
2007
|
+
if (config.guards !== void 0) {
|
|
2008
|
+
if (typeof config.guards !== "object" || Array.isArray(config.guards)) {
|
|
2009
|
+
errors.push({ code: "GUARD_INVALID", message: "Config guards must be an object", path: "guards" });
|
|
2010
|
+
} else {
|
|
2011
|
+
for (const [name, expression] of Object.entries(config.guards)) {
|
|
2012
|
+
validateCondition(expression, name, `guards.${name}`, conditionsRegistry, errors);
|
|
2013
|
+
}
|
|
2014
|
+
}
|
|
2015
|
+
}
|
|
2016
|
+
for (const issue of resolveGuards(config).issues) {
|
|
2017
|
+
errors.push({
|
|
2018
|
+
code: issue.code,
|
|
2019
|
+
message: issue.message,
|
|
2020
|
+
...issue.path ? { path: issue.path } : {}
|
|
2021
|
+
});
|
|
2022
|
+
}
|
|
1899
2023
|
for (const [id, strategy] of Object.entries(config.strategies ?? {})) {
|
|
1900
2024
|
if (!strategy || typeof strategy !== "object") {
|
|
1901
2025
|
errors.push({ code: "STRATEGY_INVALID", message: "Strategy must be an object", strategy: id });
|
|
@@ -2015,10 +2139,10 @@ var createRunCancellation = (source) => {
|
|
|
2015
2139
|
};
|
|
2016
2140
|
};
|
|
2017
2141
|
|
|
2018
|
-
// src/
|
|
2142
|
+
// src/createRunner.ts
|
|
2019
2143
|
var createRunner = (options = {}) => {
|
|
2020
|
-
const actionsRegistry =
|
|
2021
|
-
const conditionsRegistry =
|
|
2144
|
+
const actionsRegistry = new Map(BUILTIN_ACTIONS);
|
|
2145
|
+
const conditionsRegistry = new Map(BUILTIN_CONDITIONS);
|
|
2022
2146
|
const configRef = {};
|
|
2023
2147
|
const timeout = options.timeout ?? options.timeoutMs;
|
|
2024
2148
|
const runnerOptions = timeout === void 0 ? options : { ...options, timeout };
|
|
@@ -2028,19 +2152,24 @@ var createRunner = (options = {}) => {
|
|
|
2028
2152
|
console.warn("timeoutMs is deprecated; use timeout. It will be removed in a future major release.");
|
|
2029
2153
|
}
|
|
2030
2154
|
const environment = {
|
|
2031
|
-
actionsRegistry,
|
|
2032
|
-
conditionsRegistry,
|
|
2155
|
+
registry: { actions: actionsRegistry, conditions: conditionsRegistry },
|
|
2033
2156
|
configRef,
|
|
2034
2157
|
options: runnerOptions,
|
|
2035
2158
|
mergeData
|
|
2036
2159
|
};
|
|
2037
2160
|
const registerAction = (name, action) => {
|
|
2161
|
+
if (BUILTIN_ACTION_NAMES.has(name)) {
|
|
2162
|
+
throw new Error(`Cannot override built-in action "${name}"`);
|
|
2163
|
+
}
|
|
2038
2164
|
actionsRegistry.set(name, action);
|
|
2039
2165
|
};
|
|
2040
2166
|
const registerActions = (items) => {
|
|
2041
2167
|
Object.entries(items).forEach(([name, action]) => registerAction(name, action));
|
|
2042
2168
|
};
|
|
2043
2169
|
const registerCondition = (name, condition) => {
|
|
2170
|
+
if (BUILTIN_CONDITION_NAMES.has(name)) {
|
|
2171
|
+
throw new Error(`Cannot override built-in condition "${name}"`);
|
|
2172
|
+
}
|
|
2044
2173
|
conditionsRegistry.set(name, condition);
|
|
2045
2174
|
};
|
|
2046
2175
|
const registerConditions = (items) => {
|
|
@@ -2051,7 +2180,7 @@ var createRunner = (options = {}) => {
|
|
|
2051
2180
|
return { ...result, warnings: [...result.warnings, ...runnerLimitWarnings(runnerOptions)] };
|
|
2052
2181
|
};
|
|
2053
2182
|
const loadConfig = (nextConfig) => {
|
|
2054
|
-
configRef.current = nextConfig;
|
|
2183
|
+
configRef.current = resolveGuards(nextConfig).config;
|
|
2055
2184
|
return validateConfig2(nextConfig);
|
|
2056
2185
|
};
|
|
2057
2186
|
const runInternal = (entrypoint, context, input, sync, runOptions) => {
|
|
@@ -2137,7 +2266,7 @@ var parseDomBinding = (binding, prefix) => {
|
|
|
2137
2266
|
return separator <= 0 || separator === source.length - 1 ? void 0 : { selector: source.slice(0, separator), eventType: source.slice(separator + 1) };
|
|
2138
2267
|
};
|
|
2139
2268
|
|
|
2140
|
-
// src/
|
|
2269
|
+
// src/createFlow.ts
|
|
2141
2270
|
var busBindingPrefix = "[bus] ";
|
|
2142
2271
|
var domBindingPrefix = "[dom] ";
|
|
2143
2272
|
var defaultMaxQueueSize = 50;
|
|
@@ -2378,10 +2507,11 @@ var createFlow = (definition, options) => {
|
|
|
2378
2507
|
return { runner, start, stop };
|
|
2379
2508
|
};
|
|
2380
2509
|
|
|
2381
|
-
// src/
|
|
2510
|
+
// src/createWS.ts
|
|
2382
2511
|
var openState = 1;
|
|
2383
2512
|
var maxSeenEvents = 1e3;
|
|
2384
2513
|
var createWS = (options) => {
|
|
2514
|
+
console.warn("[slapflow] createWS is deprecated and will be removed soon. Use createWebSocket instead.");
|
|
2385
2515
|
const inboundTopics = new Set(options.inboundTopics ?? []);
|
|
2386
2516
|
const outboundTopics = new Set(options.outboundTopics ?? []);
|
|
2387
2517
|
const seenEventIds = /* @__PURE__ */ new Set();
|
|
@@ -2393,6 +2523,14 @@ var createWS = (options) => {
|
|
|
2393
2523
|
let started = false;
|
|
2394
2524
|
let currentStatus = "idle";
|
|
2395
2525
|
const diagnosticsBus = options.bus;
|
|
2526
|
+
const isInboundTopic = (topic) => {
|
|
2527
|
+
for (const pattern of inboundTopics) {
|
|
2528
|
+
if (matchesTopic(topic, pattern)) {
|
|
2529
|
+
return true;
|
|
2530
|
+
}
|
|
2531
|
+
}
|
|
2532
|
+
return false;
|
|
2533
|
+
};
|
|
2396
2534
|
const emitDiagnostic = (topic, payload) => {
|
|
2397
2535
|
diagnosticsBus.emit(topic, payload, {
|
|
2398
2536
|
...options.origin ? { origin: options.origin } : {}
|
|
@@ -2470,7 +2608,7 @@ var createWS = (options) => {
|
|
|
2470
2608
|
if (typeof data === "string") {
|
|
2471
2609
|
try {
|
|
2472
2610
|
const busEvent = JSON.parse(data);
|
|
2473
|
-
if (busEvent.topic &&
|
|
2611
|
+
if (busEvent.topic && isInboundTopic(busEvent.topic)) {
|
|
2474
2612
|
if (busEvent.id) {
|
|
2475
2613
|
rememberEvent(busEvent.id);
|
|
2476
2614
|
}
|
|
@@ -2537,7 +2675,117 @@ var createWS = (options) => {
|
|
|
2537
2675
|
return { start, stop, reconnect, status: () => currentStatus };
|
|
2538
2676
|
};
|
|
2539
2677
|
|
|
2540
|
-
// src/
|
|
2678
|
+
// src/createWebSocket.ts
|
|
2679
|
+
var createWebSocket = (options) => {
|
|
2680
|
+
let socket;
|
|
2681
|
+
let retryTimer;
|
|
2682
|
+
let retryAttempt = 0;
|
|
2683
|
+
let started = false;
|
|
2684
|
+
let currentStatus = "idle";
|
|
2685
|
+
const emitSocketEvent = (topic, payload) => {
|
|
2686
|
+
options.bus.dispatch({
|
|
2687
|
+
id: createId(),
|
|
2688
|
+
topic,
|
|
2689
|
+
occurredAt: Date.now(),
|
|
2690
|
+
...options.origin ? { origin: options.origin } : {},
|
|
2691
|
+
parsed: payload,
|
|
2692
|
+
serialized: JSON.stringify(payload)
|
|
2693
|
+
});
|
|
2694
|
+
};
|
|
2695
|
+
const scheduleRetry = () => {
|
|
2696
|
+
const delay = getRetryDelay(retryAttempt, options.reconnect ?? {});
|
|
2697
|
+
const attempt = retryAttempt + 1;
|
|
2698
|
+
currentStatus = "reconnecting";
|
|
2699
|
+
retryAttempt = attempt;
|
|
2700
|
+
retryTimer = setTimeout(() => {
|
|
2701
|
+
retryTimer = void 0;
|
|
2702
|
+
connect();
|
|
2703
|
+
}, delay);
|
|
2704
|
+
};
|
|
2705
|
+
const connect = () => {
|
|
2706
|
+
if (!started || socket) {
|
|
2707
|
+
return;
|
|
2708
|
+
}
|
|
2709
|
+
currentStatus = "connecting";
|
|
2710
|
+
try {
|
|
2711
|
+
const current = new WebSocket(options.url, options.protocols ?? []);
|
|
2712
|
+
socket = current;
|
|
2713
|
+
current.addEventListener("open", () => {
|
|
2714
|
+
if (socket === current) {
|
|
2715
|
+
retryAttempt = 0;
|
|
2716
|
+
currentStatus = "connected";
|
|
2717
|
+
emitSocketEvent("open", { url: options.url });
|
|
2718
|
+
}
|
|
2719
|
+
});
|
|
2720
|
+
current.addEventListener("message", (event) => {
|
|
2721
|
+
if (socket !== current) {
|
|
2722
|
+
return;
|
|
2723
|
+
}
|
|
2724
|
+
let parsed = event.data;
|
|
2725
|
+
if (typeof parsed === "string") {
|
|
2726
|
+
try {
|
|
2727
|
+
parsed = JSON.parse(parsed);
|
|
2728
|
+
} catch {
|
|
2729
|
+
parsed = event.data;
|
|
2730
|
+
}
|
|
2731
|
+
}
|
|
2732
|
+
emitSocketEvent("message", parsed);
|
|
2733
|
+
});
|
|
2734
|
+
current.addEventListener("close", (event) => {
|
|
2735
|
+
if (socket !== current) {
|
|
2736
|
+
return;
|
|
2737
|
+
}
|
|
2738
|
+
socket = void 0;
|
|
2739
|
+
emitSocketEvent("close", { code: event.code, reason: event.reason });
|
|
2740
|
+
if (started) {
|
|
2741
|
+
scheduleRetry();
|
|
2742
|
+
}
|
|
2743
|
+
});
|
|
2744
|
+
current.addEventListener("error", (event) => {
|
|
2745
|
+
emitSocketEvent("error", { error: event });
|
|
2746
|
+
});
|
|
2747
|
+
} catch (error) {
|
|
2748
|
+
socket = void 0;
|
|
2749
|
+
emitSocketEvent("error", { error });
|
|
2750
|
+
if (started) {
|
|
2751
|
+
scheduleRetry();
|
|
2752
|
+
}
|
|
2753
|
+
}
|
|
2754
|
+
};
|
|
2755
|
+
const start = () => {
|
|
2756
|
+
if (!started) {
|
|
2757
|
+
started = true;
|
|
2758
|
+
connect();
|
|
2759
|
+
}
|
|
2760
|
+
};
|
|
2761
|
+
const stop = () => {
|
|
2762
|
+
started = false;
|
|
2763
|
+
if (retryTimer) {
|
|
2764
|
+
clearTimeout(retryTimer);
|
|
2765
|
+
}
|
|
2766
|
+
retryTimer = void 0;
|
|
2767
|
+
const current = socket;
|
|
2768
|
+
socket = void 0;
|
|
2769
|
+
current?.close();
|
|
2770
|
+
currentStatus = "stopped";
|
|
2771
|
+
};
|
|
2772
|
+
const reconnect = () => {
|
|
2773
|
+
if (!started) {
|
|
2774
|
+
return;
|
|
2775
|
+
}
|
|
2776
|
+
if (retryTimer) {
|
|
2777
|
+
clearTimeout(retryTimer);
|
|
2778
|
+
retryTimer = void 0;
|
|
2779
|
+
}
|
|
2780
|
+
const current = socket;
|
|
2781
|
+
socket = void 0;
|
|
2782
|
+
current?.close();
|
|
2783
|
+
connect();
|
|
2784
|
+
};
|
|
2785
|
+
return { start, stop, reconnect, status: () => currentStatus };
|
|
2786
|
+
};
|
|
2787
|
+
|
|
2788
|
+
// src/helpers/catchError.ts
|
|
2541
2789
|
var catchError = (callback) => new Promise((resolve, reject) => {
|
|
2542
2790
|
try {
|
|
2543
2791
|
resolve(callback());
|
|
@@ -2547,14 +2795,17 @@ var catchError = (callback) => new Promise((resolve, reject) => {
|
|
|
2547
2795
|
});
|
|
2548
2796
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2549
2797
|
0 && (module.exports = {
|
|
2798
|
+
BUILTIN_ACTIONS,
|
|
2799
|
+
BUILTIN_ACTION_NAMES,
|
|
2800
|
+
BUILTIN_CONDITIONS,
|
|
2801
|
+
BUILTIN_CONDITION_NAMES,
|
|
2550
2802
|
PubSub,
|
|
2551
2803
|
catchError,
|
|
2552
|
-
createActionsRegistry,
|
|
2553
|
-
createConditionsRegistry,
|
|
2554
2804
|
createFlow,
|
|
2555
2805
|
createMemoryTraceSink,
|
|
2556
2806
|
createPubSub,
|
|
2557
2807
|
createWS,
|
|
2808
|
+
createWebSocket,
|
|
2558
2809
|
defineConfig,
|
|
2559
2810
|
defineErrorReporter
|
|
2560
2811
|
});
|