@pumped-fn/core-next 0.5.78 → 0.5.80

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.cjs CHANGED
@@ -11,9 +11,12 @@ var __export = (all) => {
11
11
 
12
12
  //#endregion
13
13
 
14
+ //#region src/tag-types.ts
15
+ const tagSymbol = Symbol.for("@pumped-fn/core/tag");
16
+
17
+ //#endregion
14
18
  //#region src/types.ts
15
19
  const executorSymbol = Symbol.for("@pumped-fn/core/executor");
16
- const metaSymbol = Symbol.for("@pumped-fn/core/meta");
17
20
  var SchemaError = class extends Error {
18
21
  issues;
19
22
  constructor(issues) {
@@ -97,71 +100,165 @@ function custom() {
97
100
  }
98
101
 
99
102
  //#endregion
100
- //#region src/meta.ts
101
- var MetaFunction = class {
103
+ //#region src/tag.ts
104
+ const tagCacheMap = /* @__PURE__ */ new WeakMap();
105
+ function buildTagCache(tags) {
106
+ const map = /* @__PURE__ */ new Map();
107
+ for (const tagged of tags) {
108
+ const existing = map.get(tagged.key);
109
+ if (existing) existing.push(tagged.value);
110
+ else map.set(tagged.key, [tagged.value]);
111
+ }
112
+ return map;
113
+ }
114
+ function isStore(source) {
115
+ return typeof source === "object" && source !== null && "get" in source && "set" in source && typeof source.get === "function" && typeof source.set === "function";
116
+ }
117
+ function extract(source, key, schema) {
118
+ if (source === null || source === void 0) return;
119
+ if (isStore(source)) {
120
+ const value = source.get(key);
121
+ return value === void 0 ? void 0 : validate(schema, value);
122
+ }
123
+ let cache = tagCacheMap.get(source);
124
+ if (!cache) {
125
+ cache = buildTagCache(Array.isArray(source) ? source : source.tags ?? []);
126
+ tagCacheMap.set(source, cache);
127
+ }
128
+ const values = cache.get(key);
129
+ return values && values.length > 0 ? validate(schema, values[0]) : void 0;
130
+ }
131
+ function collect(source, key, schema) {
132
+ if (isStore(source)) {
133
+ const value = source.get(key);
134
+ return value === void 0 ? [] : [validate(schema, value)];
135
+ }
136
+ let cache = tagCacheMap.get(source);
137
+ if (!cache) {
138
+ cache = buildTagCache(Array.isArray(source) ? source : source.tags ?? []);
139
+ tagCacheMap.set(source, cache);
140
+ }
141
+ const values = cache.get(key);
142
+ return values ? values.map((v) => validate(schema, v)) : [];
143
+ }
144
+ function write(store, key, schema, value) {
145
+ const validated = validate(schema, value);
146
+ store.set(key, validated);
147
+ }
148
+ function createTagged(key, schema, value, label) {
149
+ const tagged = {
150
+ [tagSymbol]: true,
151
+ key,
152
+ schema,
153
+ value,
154
+ toString() {
155
+ return `${label || key.toString()}=${JSON.stringify(value)}`;
156
+ },
157
+ get [Symbol.toStringTag]() {
158
+ return "Tagged";
159
+ }
160
+ };
161
+ Object.defineProperty(tagged, Symbol.for("nodejs.util.inspect.custom"), { value: function(depth, opts) {
162
+ return `Tagged { ${label || "anonymous"}: ${opts.stylize ? opts.stylize(JSON.stringify(value), "string") : JSON.stringify(value)} }`;
163
+ } });
164
+ return tagged;
165
+ }
166
+ var TagImpl = class {
102
167
  key;
103
168
  schema;
104
- [metaSymbol] = true;
105
- constructor(key, schema) {
106
- this.key = typeof key === "string" ? Symbol(key) : key;
169
+ label;
170
+ default;
171
+ constructor(schema, options) {
172
+ this.label = options?.label;
173
+ this.key = options?.label ? Symbol.for(options.label) : Symbol();
107
174
  this.schema = schema;
175
+ this.default = options?.default ?? void 0;
108
176
  }
109
- __call(value) {
110
- return {
111
- [metaSymbol]: true,
112
- key: this.key,
113
- schema: this.schema,
114
- value
115
- };
177
+ get(source) {
178
+ const value = extract(source, this.key, this.schema);
179
+ if (value === void 0) {
180
+ if (this.default !== void 0) return this.default;
181
+ throw new Error(`Value not found for key: ${this.key.toString()}`);
182
+ }
183
+ return value;
116
184
  }
117
- partial(d) {
118
- return Object.assign({}, this.__call({}), d);
185
+ find(source) {
186
+ const value = extract(source, this.key, this.schema);
187
+ return value !== void 0 ? value : this.default;
119
188
  }
120
189
  some(source) {
121
- return findValues(source, this);
190
+ return collect(source, this.key, this.schema);
122
191
  }
123
- find(source) {
124
- return findValue(source, this);
192
+ set(target, value) {
193
+ if (isStore(target)) {
194
+ write(target, this.key, this.schema, value);
195
+ return;
196
+ }
197
+ const validated = validate(this.schema, value);
198
+ return createTagged(this.key, this.schema, validated, this.label);
125
199
  }
126
- get(source) {
127
- const values = findValues(source, this);
128
- if (values.length === 0) throw new Error(`Meta value with key ${String(this.key)} not found`);
129
- return values[0];
200
+ entry(value) {
201
+ const val = value !== void 0 ? value : this.default;
202
+ if (val === void 0) throw new Error("Value required for entry without default");
203
+ const validated = validate(this.schema, val);
204
+ return [this.key, validated];
205
+ }
206
+ toString() {
207
+ return this.label ? `Tag(${this.label})` : `Tag(${this.key.toString()})`;
208
+ }
209
+ get [Symbol.toStringTag]() {
210
+ return this.label ? `Tag<${this.label}>` : "Tag<anonymous>";
211
+ }
212
+ [Symbol.for("nodejs.util.inspect.custom")]() {
213
+ return this.label ? `Tag { ${this.label} }` : "Tag { anonymous }";
130
214
  }
131
215
  };
132
- const meta = (key, schema) => {
133
- const metaFunc = new MetaFunction(key, schema);
134
- const fn = ((value) => metaFunc.__call(value));
216
+ function tag(schema, options) {
217
+ const impl = new TagImpl(schema, options);
218
+ const fn = ((value) => {
219
+ const val = value !== void 0 ? value : impl.default;
220
+ if (val === void 0) throw new Error("Value required for tag without default");
221
+ const validated = validate(schema, val);
222
+ return createTagged(impl.key, impl.schema, validated, impl.label);
223
+ });
135
224
  Object.defineProperty(fn, "key", {
136
- value: metaFunc.key,
225
+ value: impl.key,
137
226
  writable: false,
138
227
  configurable: false
139
228
  });
140
- Object.defineProperty(fn, metaSymbol, {
141
- value: true,
229
+ Object.defineProperty(fn, "schema", {
230
+ value: impl.schema,
142
231
  writable: false,
143
232
  configurable: false
144
233
  });
145
- fn.partial = metaFunc.partial.bind(metaFunc);
146
- fn.some = metaFunc.some.bind(metaFunc);
147
- fn.find = metaFunc.find.bind(metaFunc);
148
- fn.get = metaFunc.get.bind(metaFunc);
234
+ Object.defineProperty(fn, "label", {
235
+ value: impl.label,
236
+ writable: false,
237
+ configurable: false
238
+ });
239
+ Object.defineProperty(fn, "default", {
240
+ value: impl.default,
241
+ writable: false,
242
+ configurable: false
243
+ });
244
+ fn.get = impl.get.bind(impl);
245
+ fn.find = impl.find.bind(impl);
246
+ fn.some = impl.some.bind(impl);
247
+ fn.set = impl.set.bind(impl);
248
+ fn.entry = impl.entry.bind(impl);
249
+ fn.toString = impl.toString.bind(impl);
250
+ fn.partial = (d) => {
251
+ return Object.assign({}, createTagged(impl.key, impl.schema, {}, impl.label), d);
252
+ };
253
+ Object.defineProperty(fn, Symbol.toStringTag, { get: () => impl[Symbol.toStringTag] });
254
+ const inspectSymbol = Symbol.for("nodejs.util.inspect.custom");
255
+ Object.defineProperty(fn, inspectSymbol, { value: impl[inspectSymbol].bind(impl) });
149
256
  return fn;
150
- };
151
- function getValue(meta$1) {
152
- return validate(meta$1.schema, meta$1.value);
153
- }
154
- function findValues(executor, meta$1) {
155
- if (!executor) return [];
156
- return (Array.isArray(executor) ? executor : executor.metas ?? []).filter((m) => m.key === meta$1.key).map((m) => getValue(m));
157
- }
158
- function findValue(executor, meta$1) {
159
- return findValues(executor, meta$1).at(0);
160
257
  }
161
258
 
162
259
  //#endregion
163
260
  //#region src/executor.ts
164
- function createExecutor(factory, dependencies, metas) {
261
+ function createExecutor(factory, dependencies, tags) {
165
262
  const executor = {
166
263
  [executorSymbol]: "main",
167
264
  factory: (_, controller) => {
@@ -169,27 +266,27 @@ function createExecutor(factory, dependencies, metas) {
169
266
  return factory(_, controller);
170
267
  },
171
268
  dependencies,
172
- metas
269
+ tags
173
270
  };
174
271
  const lazyExecutor = {
175
272
  [executorSymbol]: "lazy",
176
273
  dependencies: void 0,
177
274
  executor,
178
275
  factory: void 0,
179
- metas
276
+ tags
180
277
  };
181
278
  const reactiveExecutor = {
182
279
  [executorSymbol]: "reactive",
183
280
  executor,
184
281
  factory: void 0,
185
282
  dependencies: void 0,
186
- metas
283
+ tags
187
284
  };
188
285
  const staticExecutor = {
189
286
  [executorSymbol]: "static",
190
287
  dependencies: void 0,
191
288
  factory: void 0,
192
- metas,
289
+ tags,
193
290
  executor
194
291
  };
195
292
  Object.defineProperties(executor, {
@@ -232,12 +329,12 @@ function isExecutor(input) {
232
329
  function isPreset(input) {
233
330
  return typeof input === "object" && input !== null && executorSymbol in input && input[executorSymbol] === "preset";
234
331
  }
235
- function provide(factory, ...metas) {
236
- return createExecutor(factory, void 0, metas);
332
+ function provide(factory, ...tags) {
333
+ return createExecutor(factory, void 0, tags);
237
334
  }
238
- function derive(pdependencies, pfactory, ...metas) {
335
+ function derive(pdependencies, pfactory, ...tags) {
239
336
  const factory = (deps, ctl) => pfactory(deps, ctl);
240
- return createExecutor(factory, pdependencies, metas);
337
+ return createExecutor(factory, pdependencies, tags);
241
338
  }
242
339
  function preset(e, v) {
243
340
  const executor = isExecutor(e) ? e : e.escape();
@@ -547,89 +644,12 @@ function buildDependencyChain(executorStack) {
547
644
  return executorStack.map(getExecutorName);
548
645
  }
549
646
 
550
- //#endregion
551
- //#region src/accessor.ts
552
- function isDataStore(source) {
553
- return "get" in source && "set" in source && typeof source.get === "function" && typeof source.set === "function";
554
- }
555
- function isMetaArray(source) {
556
- return Array.isArray(source);
557
- }
558
- function extractFromSource(source, key, schema) {
559
- if (isDataStore(source)) {
560
- const value = source.get(key);
561
- return value === void 0 ? void 0 : validate(schema, value);
562
- }
563
- if (isMetaArray(source)) {
564
- const meta$2 = source.find((m) => m.key === key);
565
- return meta$2 ? validate(schema, meta$2.value) : void 0;
566
- }
567
- const meta$1 = (source.metas ?? []).find((m) => m.key === key);
568
- return meta$1 ? validate(schema, meta$1.value) : void 0;
569
- }
570
- function validateAndSet(source, key, schema, value) {
571
- if (!isDataStore(source)) throw new Error("set() can only be used with DataStore");
572
- const validated = validate(schema, value);
573
- source.set(key, validated);
574
- }
575
- function validateAndPreset(key, schema, value) {
576
- return [key, validate(schema, value)];
577
- }
578
- var AccessorImpl$1 = class {
579
- key;
580
- schema;
581
- constructor(key, schema) {
582
- this.key = typeof key === "string" ? Symbol(key) : key;
583
- this.schema = schema;
584
- }
585
- get(source) {
586
- const value = extractFromSource(source, this.key, this.schema);
587
- if (value === void 0) throw new Error(`Value not found for key: ${this.key.toString()}`);
588
- return value;
589
- }
590
- find(source) {
591
- return extractFromSource(source, this.key, this.schema);
592
- }
593
- set(source, value) {
594
- validateAndSet(source, this.key, this.schema, value);
595
- }
596
- preset(value) {
597
- return validateAndPreset(this.key, this.schema, value);
598
- }
599
- };
600
- var AccessorWithDefaultImpl = class {
601
- key;
602
- schema;
603
- defaultValue;
604
- constructor(key, schema, defaultValue) {
605
- this.key = typeof key === "string" ? Symbol(key) : key;
606
- this.schema = schema;
607
- this.defaultValue = validate(schema, defaultValue);
608
- }
609
- get(source) {
610
- return extractFromSource(source, this.key, this.schema) ?? this.defaultValue;
611
- }
612
- find(source) {
613
- return extractFromSource(source, this.key, this.schema) ?? this.defaultValue;
614
- }
615
- set(source, value) {
616
- validateAndSet(source, this.key, this.schema, value);
617
- }
618
- preset(value) {
619
- return validateAndPreset(this.key, this.schema, value);
620
- }
621
- };
622
- function accessor(key, schema, defaultValue) {
623
- if (defaultValue !== void 0) return new AccessorWithDefaultImpl(key, schema, defaultValue);
624
- return new AccessorImpl$1(key, schema);
625
- }
626
-
627
647
  //#endregion
628
648
  //#region src/flow.ts
629
649
  function isErrorEntry(entry) {
630
650
  return typeof entry === "object" && entry !== null && "__error" in entry;
631
651
  }
632
- function wrapWithExtensions(extensions, baseExecutor, dataStore, operation) {
652
+ function wrapWithExtensions(extensions, baseExecutor, scope, operation) {
633
653
  if (!extensions || extensions.length === 0) return baseExecutor;
634
654
  let executor = baseExecutor;
635
655
  for (let i = extensions.length - 1; i >= 0; i--) {
@@ -637,28 +657,34 @@ function wrapWithExtensions(extensions, baseExecutor, dataStore, operation) {
637
657
  if (extension$1.wrap) {
638
658
  const current = executor;
639
659
  executor = () => {
640
- const result = extension$1.wrap(dataStore, current, operation);
660
+ const result = extension$1.wrap(scope, current, operation);
641
661
  return result instanceof Promised ? result : Promised.create(result);
642
662
  };
643
663
  }
644
664
  }
645
665
  return executor;
646
666
  }
647
- const flowDefinitionMeta = meta("flow.definition", custom());
667
+ const flowDefinitionMeta = tag(custom(), { label: "flow.definition" });
648
668
  const flowMeta = {
649
- depth: accessor("flow.depth", custom(), 0),
650
- flowName: accessor("flow.name", custom()),
651
- parentFlowName: accessor("flow.parentName", custom()),
652
- isParallel: accessor("flow.isParallel", custom(), false),
653
- journal: accessor("flow.journal", custom())
669
+ depth: tag(custom(), {
670
+ label: "flow.depth",
671
+ default: 0
672
+ }),
673
+ flowName: tag(custom(), { label: "flow.name" }),
674
+ parentFlowName: tag(custom(), { label: "flow.parentName" }),
675
+ isParallel: tag(custom(), {
676
+ label: "flow.isParallel",
677
+ default: false
678
+ }),
679
+ journal: tag(custom(), { label: "flow.journal" })
654
680
  };
655
681
  var FlowDefinition = class {
656
- constructor(name$1, version, input, output, metas = []) {
682
+ constructor(name$1, version, input, output, tags = []) {
657
683
  this.name = name$1;
658
684
  this.version = version;
659
685
  this.input = input;
660
686
  this.output = output;
661
- this.metas = metas;
687
+ this.tags = tags;
662
688
  }
663
689
  handler(dependenciesOrHandler, handlerFn) {
664
690
  if (typeof dependenciesOrHandler === "function") {
@@ -668,7 +694,7 @@ var FlowDefinition = class {
668
694
  return noDepsHandler(ctx, input);
669
695
  };
670
696
  return flowHandler;
671
- }, void 0, [...this.metas, flowDefinitionMeta(this)]);
697
+ }, void 0, [...this.tags, flowDefinitionMeta(this)]);
672
698
  executor$1.definition = this;
673
699
  return executor$1;
674
700
  }
@@ -679,26 +705,26 @@ var FlowDefinition = class {
679
705
  return dependentHandler(deps, ctx, input);
680
706
  };
681
707
  return flowHandler;
682
- }, dependencies, [...this.metas, flowDefinitionMeta(this)]);
708
+ }, dependencies, [...this.tags, flowDefinitionMeta(this)]);
683
709
  executor.definition = this;
684
710
  return executor;
685
711
  }
686
712
  };
687
713
  function define(config) {
688
- return new FlowDefinition(config.name, config.version || "1.0.0", config.input, config.output, config.meta);
714
+ return new FlowDefinition(config.name || "anonymous", config.version || "1.0.0", config.input, config.output, config.tags || []);
689
715
  }
690
716
  var FlowContext = class FlowContext {
691
717
  contextData = /* @__PURE__ */ new Map();
692
718
  journal = null;
693
719
  scope;
694
720
  reversedExtensions;
695
- metas;
696
- constructor(scope, extensions, meta$1, parent) {
721
+ tags;
722
+ constructor(scope, extensions, tags, parent) {
697
723
  this.extensions = extensions;
698
724
  this.parent = parent;
699
725
  this.scope = scope;
700
726
  this.reversedExtensions = [...extensions].reverse();
701
- this.metas = meta$1;
727
+ this.tags = tags;
702
728
  }
703
729
  resolve(executor) {
704
730
  return this.scope.resolve(executor);
@@ -711,7 +737,7 @@ var FlowContext = class FlowContext {
711
737
  for (const extension$1 of this.reversedExtensions) if (extension$1.wrap) {
712
738
  const current = executor;
713
739
  executor = () => {
714
- const result = extension$1.wrap(this, current, operation);
740
+ const result = extension$1.wrap(this.scope, current, operation);
715
741
  return result instanceof Promised ? result : Promised.create(result);
716
742
  };
717
743
  }
@@ -729,13 +755,17 @@ var FlowContext = class FlowContext {
729
755
  if (typeof accessorOrKey === "object" && accessorOrKey !== null && "get" in accessorOrKey) return accessorOrKey.get(this);
730
756
  const key = accessorOrKey;
731
757
  if (this.contextData.has(key)) return this.contextData.get(key);
758
+ if (this.tags && typeof key === "symbol") {
759
+ const tagged = this.tags.find((m) => m.key === key);
760
+ if (tagged) return tagged.value;
761
+ }
732
762
  if (this.parent) return this.parent.get(key);
733
763
  }
734
- find(accessor$1) {
735
- return accessor$1.find(this);
764
+ find(accessor) {
765
+ return accessor.find(this);
736
766
  }
737
767
  set(accessorOrKey, value) {
738
- if (typeof accessorOrKey === "object" && accessorOrKey !== null && "set" in accessorOrKey) {
768
+ if (accessorOrKey !== null && accessorOrKey !== void 0 && (typeof accessorOrKey === "object" || typeof accessorOrKey === "function") && "set" in accessorOrKey) {
739
769
  accessorOrKey.set(this, value);
740
770
  return;
741
771
  }
@@ -935,29 +965,30 @@ var FlowContext = class FlowContext {
935
965
  get: (key) => contextDataSnapshot.get(key),
936
966
  set: (_key, _value) => {
937
967
  throw new Error("Cannot set values on execution snapshot");
938
- }
968
+ },
969
+ tags: this.tags
939
970
  };
940
971
  return { context: {
941
- get(accessor$1) {
942
- return accessor$1.get(dataStore);
972
+ get(accessor) {
973
+ return accessor.get(dataStore);
943
974
  },
944
- find(accessor$1) {
945
- return accessor$1.find(dataStore);
975
+ find(accessor) {
976
+ return accessor.find(dataStore);
946
977
  }
947
978
  } };
948
979
  }
949
980
  };
950
981
  function execute(flow$1, input, options) {
951
- const scope = options?.scope || createScope({ meta: options?.scopeMeta });
982
+ const scope = options?.scope || createScope({ tags: options?.scopeTags });
952
983
  const shouldDisposeScope = !options?.scope;
953
984
  let resolveSnapshot;
954
985
  const snapshotPromise = new Promise((resolve) => {
955
986
  resolveSnapshot = resolve;
956
987
  });
957
988
  const promise = (async () => {
958
- const context = new FlowContext(scope, options?.extensions || [], options?.meta);
989
+ const context = new FlowContext(scope, options?.extensions || [], options?.tags);
959
990
  try {
960
- if (options?.initialContext) for (const [accessor$1, value] of options.initialContext) accessor$1.set(context, value);
991
+ if (options?.initialContext) for (const [accessor, value] of options.initialContext) accessor.set(context, value);
961
992
  const executeCore = () => {
962
993
  return scope.resolve(flow$1).map(async (handler) => {
963
994
  const definition$1 = flowDefinitionMeta.find(flow$1);
@@ -971,7 +1002,7 @@ function execute(flow$1, input, options) {
971
1002
  };
972
1003
  const definition = flowDefinitionMeta.find(flow$1);
973
1004
  if (!definition) throw new Error("Flow definition not found in executor metadata");
974
- const result = await wrapWithExtensions(options?.extensions, executeCore, context, {
1005
+ const result = await wrapWithExtensions(options?.extensions, executeCore, context.scope, {
975
1006
  kind: "execute",
976
1007
  flow: flow$1,
977
1008
  definition,
@@ -1012,129 +1043,100 @@ function execute(flow$1, input, options) {
1012
1043
  }
1013
1044
  return Promised.create(promise, snapshotPromise);
1014
1045
  }
1015
- function flowImpl(definitionOrConfigOrDepsOrHandler, dependenciesOrHandler, handlerFn) {
1016
- if (typeof definitionOrConfigOrDepsOrHandler === "function") {
1017
- const handler = definitionOrConfigOrDepsOrHandler;
1046
+ function flowImpl(first, second, third) {
1047
+ if (typeof first === "function") {
1048
+ const handler = first;
1018
1049
  return define({
1019
- name: "anonymous",
1020
- version: "1.0.0",
1021
1050
  input: custom(),
1022
1051
  output: custom()
1023
1052
  }).handler(handler);
1024
1053
  }
1025
- const firstArg = definitionOrConfigOrDepsOrHandler;
1026
- if (!("name" in firstArg) && dependenciesOrHandler && typeof dependenciesOrHandler === "object" && "name" in dependenciesOrHandler && handlerFn) {
1027
- const dependencies = firstArg;
1028
- const definition$1 = dependenciesOrHandler;
1029
- const hasInput$1 = "input" in definition$1 && definition$1.input !== void 0;
1030
- const hasOutput$1 = "output" in definition$1 && definition$1.output !== void 0;
1031
- return define({
1032
- name: definition$1.name,
1033
- version: definition$1.version,
1034
- input: hasInput$1 ? definition$1.input : custom(),
1035
- output: hasOutput$1 ? definition$1.output : custom(),
1036
- meta: definition$1.meta
1037
- }).handler(dependencies, handlerFn);
1038
- }
1039
- if (typeof dependenciesOrHandler === "function" && !("name" in firstArg)) {
1040
- const dependencies = firstArg;
1041
- const handler = dependenciesOrHandler;
1054
+ if (isExecutor(first)) {
1055
+ if (typeof second !== "function") throw new Error("flow(deps, handler) requires handler as second argument");
1056
+ const dependencies = first;
1057
+ const handler = second;
1042
1058
  return define({
1043
- name: "anonymous",
1044
- version: "1.0.0",
1045
1059
  input: custom(),
1046
1060
  output: custom()
1047
1061
  }).handler(dependencies, handler);
1048
1062
  }
1049
- if ("handler" in firstArg) {
1050
- const config = firstArg;
1051
- const hasInput$1 = "input" in config && config.input !== void 0;
1052
- const hasOutput$1 = "output" in config && config.output !== void 0;
1053
- const def$1 = define({
1054
- name: config.name,
1055
- version: config.version,
1056
- input: hasInput$1 ? config.input : custom(),
1057
- output: hasOutput$1 ? config.output : custom(),
1058
- meta: config.meta
1059
- });
1060
- if ("dependencies" in config) {
1061
- const depsConfig = config;
1062
- return def$1.handler(depsConfig.dependencies, depsConfig.handler);
1063
- } else {
1064
- const handlerConfig = config;
1065
- return def$1.handler(handlerConfig.handler);
1063
+ if (typeof first === "object" && first !== null) {
1064
+ if ("input" in first && "output" in first) {
1065
+ const config = first;
1066
+ if ("handler" in config || "dependencies" in config) throw new Error("Config object cannot contain 'handler' or 'dependencies' properties. Use flow(config, handler) or flow(config, deps, handler) instead.");
1067
+ const def = define(config);
1068
+ if (!second) return def;
1069
+ if (typeof second === "function") return def.handler(second);
1070
+ if (isExecutor(second)) {
1071
+ if (!third) throw new Error("flow(config, deps, handler) requires handler as third argument");
1072
+ return def.handler(second, third);
1073
+ }
1074
+ throw new Error("Invalid flow() call: second argument must be handler function or dependencies");
1066
1075
  }
1076
+ const isValidDependencyObject = (obj) => {
1077
+ const values = Object.values(obj);
1078
+ if (values.length === 0) return true;
1079
+ return values.every((value) => typeof value === "function" || isExecutor(value));
1080
+ };
1081
+ if (!isValidDependencyObject(first)) throw new Error("Invalid flow() call: first argument must be either a config object with 'input' and 'output' properties, or a valid dependency object containing executors/functions");
1082
+ if (typeof second === "function") {
1083
+ const dependencies = first;
1084
+ const handler = second;
1085
+ return define({
1086
+ input: custom(),
1087
+ output: custom()
1088
+ }).handler(dependencies, handler);
1089
+ }
1090
+ throw new Error("Invalid flow() call: object dependencies require handler function as second argument");
1067
1091
  }
1068
- const definition = firstArg;
1069
- const hasInput = "input" in definition && definition.input !== void 0;
1070
- const hasOutput = "output" in definition && definition.output !== void 0;
1071
- const def = define({
1072
- name: definition.name || "anonymous",
1073
- version: definition.version,
1074
- input: hasInput ? definition.input : custom(),
1075
- output: hasOutput ? definition.output : custom(),
1076
- meta: definition.meta
1077
- });
1078
- if (!dependenciesOrHandler) return def;
1079
- if (typeof dependenciesOrHandler === "function") return def.handler(dependenciesOrHandler);
1080
- else return def.handler(dependenciesOrHandler, handlerFn);
1092
+ throw new Error("Invalid flow() call: first argument must be handler, dependencies, or config object");
1081
1093
  }
1082
- const flow = Object.assign(flowImpl, {
1083
- define,
1084
- execute
1085
- });
1094
+ const flow = Object.assign(flowImpl, { execute });
1086
1095
 
1087
1096
  //#endregion
1088
1097
  //#region src/scope.ts
1089
1098
  var AccessorImpl = class {
1090
- metas;
1099
+ tags;
1091
1100
  scope;
1092
1101
  requestor;
1093
1102
  currentPromise = null;
1094
1103
  currentPromised = null;
1095
- cachedResolvedPromised = null;
1096
1104
  resolve;
1097
- constructor(scope, requestor, metas) {
1105
+ constructor(scope, requestor, tags) {
1098
1106
  this.scope = scope;
1099
1107
  this.requestor = requestor;
1100
- this.metas = metas;
1108
+ this.tags = tags;
1101
1109
  this.resolve = this.createResolveFunction();
1102
- const existing = this.scope["cache"].get(requestor);
1103
- if (!existing || !existing.accessor) this.scope["cache"].set(requestor, {
1104
- accessor: this,
1105
- value: existing?.value
1106
- });
1110
+ const state = this.scope["getOrCreateState"](requestor);
1111
+ if (!state.accessor) state.accessor = this;
1107
1112
  }
1108
1113
  async resolveCore() {
1109
1114
  const { factory, dependencies, immediateValue } = this.processReplacer();
1110
1115
  if (immediateValue !== void 0) {
1111
1116
  await new Promise((resolve) => queueMicrotask(resolve));
1112
- this.scope["cache"].set(this.requestor, {
1113
- accessor: this,
1114
- value: {
1115
- kind: "resolved",
1116
- value: immediateValue,
1117
- promised: Promised.create(Promise.resolve(immediateValue))
1118
- }
1119
- });
1117
+ const state$1 = this.scope["getOrCreateState"](this.requestor);
1118
+ state$1.accessor = this;
1119
+ state$1.value = {
1120
+ kind: "resolved",
1121
+ value: immediateValue,
1122
+ promised: Promised.create(Promise.resolve(immediateValue))
1123
+ };
1120
1124
  return immediateValue;
1121
1125
  }
1122
1126
  const controller = this.createController();
1123
1127
  const resolvedDependencies = await this.scope["~resolveDependencies"](dependencies, this.requestor);
1124
1128
  const result = await this.executeFactory(factory, resolvedDependencies, controller);
1125
1129
  const processedResult = await this.processChangeEvents(result);
1126
- this.scope["cache"].set(this.requestor, {
1127
- accessor: this,
1128
- value: {
1129
- kind: "resolved",
1130
- value: processedResult,
1131
- promised: Promised.create(Promise.resolve(processedResult))
1132
- }
1133
- });
1130
+ const state = this.scope["getOrCreateState"](this.requestor);
1131
+ state.accessor = this;
1132
+ state.value = {
1133
+ kind: "resolved",
1134
+ value: processedResult,
1135
+ promised: Promised.create(Promise.resolve(processedResult))
1136
+ };
1134
1137
  this.scope["~removeFromResolutionChain"](this.requestor);
1135
1138
  this.currentPromise = null;
1136
1139
  this.currentPromised = null;
1137
- this.cachedResolvedPromised = null;
1138
1140
  return processedResult;
1139
1141
  }
1140
1142
  async resolveWithErrorHandling() {
@@ -1142,15 +1144,14 @@ var AccessorImpl = class {
1142
1144
  return await this.resolveCore();
1143
1145
  } catch (error) {
1144
1146
  const { enhancedError, errorContext, originalError } = this.enhanceResolutionError(error);
1145
- this.scope["cache"].set(this.requestor, {
1146
- accessor: this,
1147
- value: {
1148
- kind: "rejected",
1149
- error: originalError,
1150
- context: errorContext,
1151
- enhancedError
1152
- }
1153
- });
1147
+ const state = this.scope["getOrCreateState"](this.requestor);
1148
+ state.accessor = this;
1149
+ state.value = {
1150
+ kind: "rejected",
1151
+ error: originalError,
1152
+ context: errorContext,
1153
+ enhancedError
1154
+ };
1154
1155
  this.scope["~removeFromResolutionChain"](this.requestor);
1155
1156
  this.scope["~triggerError"](enhancedError, this.requestor);
1156
1157
  this.currentPromise = null;
@@ -1169,23 +1170,18 @@ var AccessorImpl = class {
1169
1170
  }
1170
1171
  this.scope["~addToResolutionChain"](this.requestor, this.requestor);
1171
1172
  this.currentPromise = this.resolveWithErrorHandling();
1172
- this.scope["cache"].set(this.requestor, {
1173
- accessor: this,
1174
- value: {
1175
- kind: "pending",
1176
- promise: this.currentPromise
1177
- }
1178
- });
1173
+ const state = this.scope["getOrCreateState"](this.requestor);
1174
+ state.accessor = this;
1175
+ state.value = {
1176
+ kind: "pending",
1177
+ promise: this.currentPromise
1178
+ };
1179
1179
  this.currentPromised = Promised.create(this.currentPromise);
1180
1180
  return this.currentPromised;
1181
1181
  };
1182
1182
  }
1183
1183
  handleCachedState(cached) {
1184
- if (cached.kind === "resolved") {
1185
- if (cached.promised) return cached.promised;
1186
- if (!this.cachedResolvedPromised) this.cachedResolvedPromised = Promised.create(Promise.resolve(cached.value));
1187
- return this.cachedResolvedPromised;
1188
- }
1184
+ if (cached.kind === "resolved") return cached.promised;
1189
1185
  if (cached.kind === "rejected") throw cached.error;
1190
1186
  if (!this.currentPromised) this.currentPromised = Promised.create(cached.promise);
1191
1187
  return this.currentPromised;
@@ -1289,9 +1285,8 @@ var AccessorImpl = class {
1289
1285
  createController() {
1290
1286
  return {
1291
1287
  cleanup: (cleanup) => {
1292
- const currentSet = this.scope["cleanups"].get(this.requestor) ?? /* @__PURE__ */ new Set();
1293
- this.scope["cleanups"].set(this.requestor, currentSet);
1294
- currentSet.add(cleanup);
1288
+ const state = this.scope["getOrCreateState"](this.requestor);
1289
+ this.scope["ensureCleanups"](state).add(cleanup);
1295
1290
  },
1296
1291
  release: () => this.scope.release(this.requestor),
1297
1292
  reload: () => this.scope.resolve(this.requestor, true).map(() => void 0),
@@ -1303,25 +1298,21 @@ function getExecutor(e) {
1303
1298
  if (isLazyExecutor(e) || isReactiveExecutor(e) || isStaticExecutor(e)) return e.executor;
1304
1299
  return e;
1305
1300
  }
1306
- var BaseScope = class BaseScope {
1301
+ var BaseScope = class {
1307
1302
  disposed = false;
1308
1303
  cache = /* @__PURE__ */ new Map();
1309
- cleanups = /* @__PURE__ */ new Map();
1310
- onUpdateCallbacks = /* @__PURE__ */ new Map();
1311
- onUpdateExecutors = /* @__PURE__ */ new Map();
1312
1304
  onEvents = {
1313
1305
  change: /* @__PURE__ */ new Set(),
1314
1306
  release: /* @__PURE__ */ new Set(),
1315
1307
  error: /* @__PURE__ */ new Set()
1316
1308
  };
1317
- onErrors = /* @__PURE__ */ new Map();
1318
1309
  isDisposing = false;
1319
- resolutionChain = /* @__PURE__ */ new Map();
1310
+ CIRCULAR_CHECK_THRESHOLD = 15;
1320
1311
  extensions = [];
1321
1312
  reversedExtensions = [];
1322
1313
  registry = [];
1323
1314
  initialValues = [];
1324
- metas;
1315
+ tags;
1325
1316
  static emptyDataStore = {
1326
1317
  get: () => void 0,
1327
1318
  set: () => void 0
@@ -1329,11 +1320,39 @@ var BaseScope = class BaseScope {
1329
1320
  constructor(options) {
1330
1321
  if (options?.registry) this.registry = [...options.registry];
1331
1322
  if (options?.initialValues) this.initialValues = options.initialValues;
1332
- if (options?.meta) this.metas = options.meta;
1323
+ if (options?.tags) this.tags = options.tags;
1333
1324
  if (options?.extensions) for (const extension$1 of options.extensions) this.useExtension(extension$1);
1334
1325
  }
1326
+ getOrCreateState(executor) {
1327
+ let state = this.cache.get(executor);
1328
+ if (!state) {
1329
+ state = { accessor: null };
1330
+ this.cache.set(executor, state);
1331
+ }
1332
+ return state;
1333
+ }
1334
+ ensureCleanups(state) {
1335
+ if (!state.cleanups) state.cleanups = /* @__PURE__ */ new Set();
1336
+ return state.cleanups;
1337
+ }
1338
+ ensureCallbacks(state) {
1339
+ if (!state.onUpdateCallbacks) state.onUpdateCallbacks = /* @__PURE__ */ new Set();
1340
+ return state.onUpdateCallbacks;
1341
+ }
1342
+ ensureExecutors(state) {
1343
+ if (!state.onUpdateExecutors) state.onUpdateExecutors = /* @__PURE__ */ new Set();
1344
+ return state.onUpdateExecutors;
1345
+ }
1346
+ ensureErrors(state) {
1347
+ if (!state.onErrors) state.onErrors = /* @__PURE__ */ new Set();
1348
+ return state.onErrors;
1349
+ }
1350
+ ensureResolutionChain(state) {
1351
+ if (!state.resolutionChain) state.resolutionChain = /* @__PURE__ */ new Set();
1352
+ return state.resolutionChain;
1353
+ }
1335
1354
  "~checkCircularDependency"(executor, resolvingExecutor) {
1336
- const currentChain = this.resolutionChain.get(resolvingExecutor);
1355
+ const currentChain = this.cache.get(resolvingExecutor)?.resolutionChain;
1337
1356
  if (currentChain && currentChain.has(executor)) {
1338
1357
  const chainArray = Array.from(currentChain);
1339
1358
  const dependencyChain = buildDependencyChain(chainArray);
@@ -1344,40 +1363,46 @@ var BaseScope = class BaseScope {
1344
1363
  }
1345
1364
  }
1346
1365
  "~addToResolutionChain"(executor, resolvingExecutor) {
1347
- const currentChain = this.resolutionChain.get(resolvingExecutor) || /* @__PURE__ */ new Set();
1348
- currentChain.add(executor);
1349
- this.resolutionChain.set(resolvingExecutor, currentChain);
1366
+ const state = this.getOrCreateState(resolvingExecutor);
1367
+ this.ensureResolutionChain(state).add(executor);
1350
1368
  }
1351
1369
  "~removeFromResolutionChain"(executor) {
1352
- this.resolutionChain.delete(executor);
1370
+ const state = this.cache.get(executor);
1371
+ if (state) {
1372
+ delete state.resolutionDepth;
1373
+ delete state.resolutionChain;
1374
+ }
1353
1375
  }
1354
1376
  "~propagateResolutionChain"(fromExecutor, toExecutor) {
1355
- const fromChain = this.resolutionChain.get(fromExecutor);
1356
- if (fromChain) {
1357
- const newChain = new Set(fromChain);
1377
+ const fromState = this.cache.get(fromExecutor);
1378
+ if (fromState?.resolutionChain) {
1379
+ const toState = this.getOrCreateState(toExecutor);
1380
+ const newChain = new Set(fromState.resolutionChain);
1358
1381
  newChain.add(fromExecutor);
1359
- this.resolutionChain.set(toExecutor, newChain);
1382
+ toState.resolutionChain = newChain;
1360
1383
  }
1361
1384
  }
1362
1385
  async "~triggerCleanup"(e) {
1363
- const cs = this.cleanups.get(e);
1364
- if (cs) for (const c of Array.from(cs.values()).reverse()) await c();
1386
+ const state = this.cache.get(e);
1387
+ if (state?.cleanups) {
1388
+ for (const c of Array.from(state.cleanups.values()).reverse()) await c();
1389
+ delete state.cleanups;
1390
+ }
1365
1391
  }
1366
1392
  async "~triggerUpdate"(e) {
1367
- const ce = this.cache.get(e);
1368
- if (!ce) throw new Error("Executor is not yet resolved");
1369
- const executors = this.onUpdateExecutors.get(e);
1370
- if (executors) for (const t of Array.from(executors.values())) {
1371
- if (this.cleanups.has(t)) this["~triggerCleanup"](t);
1372
- await this.cache.get(t).accessor.resolve(true);
1373
- if (this.onUpdateExecutors.has(t) || this.onUpdateCallbacks.has(t)) await this["~triggerUpdate"](t);
1393
+ const state = this.cache.get(e);
1394
+ if (!state) throw new Error("Executor is not yet resolved");
1395
+ if (state.onUpdateExecutors) for (const t of Array.from(state.onUpdateExecutors.values())) {
1396
+ const depState = this.cache.get(t);
1397
+ if (depState?.cleanups) this["~triggerCleanup"](t);
1398
+ await depState.accessor.resolve(true);
1399
+ if (depState.onUpdateExecutors || depState.onUpdateCallbacks) await this["~triggerUpdate"](t);
1374
1400
  }
1375
- const callbacks = this.onUpdateCallbacks.get(e);
1376
- if (callbacks) for (const cb of Array.from(callbacks.values())) await cb(ce.accessor);
1401
+ if (state.onUpdateCallbacks) for (const cb of Array.from(state.onUpdateCallbacks.values())) await cb(state.accessor);
1377
1402
  }
1378
1403
  async "~triggerError"(error, executor) {
1379
- const executorCallbacks = this.onErrors.get(executor);
1380
- if (executorCallbacks) for (const callback of Array.from(executorCallbacks.values())) try {
1404
+ const state = this.cache.get(executor);
1405
+ if (state?.onErrors) for (const callback of Array.from(state.onErrors.values())) try {
1381
1406
  await callback(error, executor, this);
1382
1407
  } catch (callbackError) {
1383
1408
  console.error("Error in error callback:", callbackError);
@@ -1395,14 +1420,25 @@ var BaseScope = class BaseScope {
1395
1420
  }
1396
1421
  async "~resolveExecutor"(ie, ref) {
1397
1422
  const e = getExecutor(ie);
1398
- this["~checkCircularDependency"](e, ref);
1399
- this["~propagateResolutionChain"](ref, e);
1423
+ if (e === ref) {
1424
+ const executorName = getExecutorName(e);
1425
+ throw createDependencyError(codes.CIRCULAR_DEPENDENCY, executorName, [executorName], executorName, void 0, {
1426
+ circularPath: `${executorName} -> ${executorName}`,
1427
+ detectedAt: executorName
1428
+ });
1429
+ }
1430
+ const currentDepth = (this.cache.get(ref)?.resolutionDepth ?? 0) + 1;
1431
+ const state = this.getOrCreateState(e);
1432
+ state.resolutionDepth = currentDepth;
1433
+ if (currentDepth > this.CIRCULAR_CHECK_THRESHOLD) {
1434
+ this["~checkCircularDependency"](e, ref);
1435
+ this["~propagateResolutionChain"](ref, e);
1436
+ }
1400
1437
  const a = this["~makeAccessor"](e);
1401
1438
  if (isLazyExecutor(ie)) return a;
1402
1439
  if (isReactiveExecutor(ie)) {
1403
- const c = this.onUpdateExecutors.get(ie.executor) ?? /* @__PURE__ */ new Set();
1404
- this.onUpdateExecutors.set(ie.executor, c);
1405
- c.add(ref);
1440
+ const parentState = this.getOrCreateState(ie.executor);
1441
+ this.ensureExecutors(parentState).add(ref);
1406
1442
  }
1407
1443
  await a.resolve(false);
1408
1444
  if (isStaticExecutor(ie)) return a;
@@ -1424,12 +1460,12 @@ var BaseScope = class BaseScope {
1424
1460
  "~ensureNotDisposed"() {
1425
1461
  if (this.disposed) throw new Error("Scope is disposed");
1426
1462
  }
1427
- wrapWithExtensions(baseExecutor, dataStore, operation) {
1463
+ wrapWithExtensions(baseExecutor, operation) {
1428
1464
  let executor = baseExecutor;
1429
1465
  for (const extension$1 of this.reversedExtensions) if (extension$1.wrap) {
1430
1466
  const current = executor;
1431
1467
  executor = () => {
1432
- const result = extension$1.wrap(dataStore, current, operation);
1468
+ const result = extension$1.wrap(this, current, operation);
1433
1469
  return result instanceof Promised ? result : Promised.create(result);
1434
1470
  };
1435
1471
  }
@@ -1439,7 +1475,7 @@ var BaseScope = class BaseScope {
1439
1475
  let requestor = isLazyExecutor(e) || isReactiveExecutor(e) || isStaticExecutor(e) ? e.executor : e;
1440
1476
  const cachedAccessor = this.cache.get(requestor);
1441
1477
  if (cachedAccessor && cachedAccessor.accessor) return cachedAccessor.accessor;
1442
- return new AccessorImpl(this, requestor, e.metas);
1478
+ return new AccessorImpl(this, requestor, e.tags);
1443
1479
  }
1444
1480
  accessor(executor) {
1445
1481
  this["~ensureNotDisposed"]();
@@ -1457,10 +1493,10 @@ var BaseScope = class BaseScope {
1457
1493
  resolve(executor, force = false) {
1458
1494
  this["~ensureNotDisposed"]();
1459
1495
  const coreResolve = () => {
1460
- const accessor$1 = this["~makeAccessor"](executor);
1461
- return accessor$1.resolve(force).map(() => accessor$1.get());
1496
+ const accessor = this["~makeAccessor"](executor);
1497
+ return accessor.resolve(force).map(() => accessor.get());
1462
1498
  };
1463
- return this.wrapWithExtensions(coreResolve, BaseScope.emptyDataStore, {
1499
+ return this.wrapWithExtensions(coreResolve, {
1464
1500
  kind: "resolve",
1465
1501
  executor,
1466
1502
  scope: this,
@@ -1469,8 +1505,23 @@ var BaseScope = class BaseScope {
1469
1505
  }
1470
1506
  resolveAccessor(executor, force = false) {
1471
1507
  this["~ensureNotDisposed"]();
1472
- const accessor$1 = this["~makeAccessor"](executor);
1473
- return accessor$1.resolve(force).map(() => accessor$1);
1508
+ const accessor = this["~makeAccessor"](executor);
1509
+ return accessor.resolve(force).map(() => accessor);
1510
+ }
1511
+ run(dependencies, callback, args) {
1512
+ this["~ensureNotDisposed"]();
1513
+ const dummyExecutor = {
1514
+ [executorSymbol]: "main",
1515
+ factory: void 0,
1516
+ dependencies,
1517
+ tags: {}
1518
+ };
1519
+ return Promised.create((async () => {
1520
+ const deps = dependencies;
1521
+ const resolvedDeps = await this["~resolveDependencies"](deps, dummyExecutor);
1522
+ if (args !== void 0 && args.length > 0) return await callback(resolvedDeps, ...args);
1523
+ return await callback(resolvedDeps, ...[]);
1524
+ })());
1474
1525
  }
1475
1526
  update(e, u) {
1476
1527
  if (this.isDisposing) return Promised.create(Promise.resolve());
@@ -1478,30 +1529,29 @@ var BaseScope = class BaseScope {
1478
1529
  const coreUpdate = () => {
1479
1530
  return Promised.create((async () => {
1480
1531
  this["~triggerCleanup"](e);
1481
- const accessor$1 = this["~makeAccessor"](e);
1532
+ const accessor = this["~makeAccessor"](e);
1482
1533
  let value;
1483
- if (typeof u === "function") value = u(accessor$1.get());
1534
+ if (typeof u === "function") value = u(accessor.get());
1484
1535
  else value = u;
1485
1536
  const events = this.onEvents.change;
1486
1537
  for (const event of events) {
1487
1538
  const updated = await event("update", e, value, this);
1488
1539
  if (updated !== void 0 && e === updated.executor) value = updated.value;
1489
1540
  }
1490
- this.cache.set(e, {
1491
- accessor: accessor$1,
1492
- value: {
1493
- kind: "resolved",
1494
- value,
1495
- promised: Promised.create(Promise.resolve(value))
1496
- }
1497
- });
1541
+ const state = this.getOrCreateState(e);
1542
+ state.accessor = accessor;
1543
+ state.value = {
1544
+ kind: "resolved",
1545
+ value,
1546
+ promised: Promised.create(Promise.resolve(value))
1547
+ };
1498
1548
  await this["~triggerUpdate"](e);
1499
1549
  })());
1500
1550
  };
1501
1551
  const baseUpdater = () => {
1502
1552
  return coreUpdate().map(() => this.accessor(e).get());
1503
1553
  };
1504
- return this.wrapWithExtensions(baseUpdater, BaseScope.emptyDataStore, {
1554
+ return this.wrapWithExtensions(baseUpdater, {
1505
1555
  kind: "resolve",
1506
1556
  operation: "update",
1507
1557
  executor: e,
@@ -1514,16 +1564,12 @@ var BaseScope = class BaseScope {
1514
1564
  release(e, s = false) {
1515
1565
  this["~ensureNotDisposed"]();
1516
1566
  const coreRelease = async () => {
1517
- if (!this.cache.get(e) && !s) throw new Error("Executor is not yet resolved");
1567
+ const state = this.cache.get(e);
1568
+ if (!state && !s) throw new Error("Executor is not yet resolved");
1518
1569
  await this["~triggerCleanup"](e);
1519
1570
  const events = this.onEvents.release;
1520
1571
  for (const event of events) await event("release", e, this);
1521
- const executors = this.onUpdateExecutors.get(e);
1522
- if (executors) {
1523
- for (const t of Array.from(executors.values())) await this.release(t, true);
1524
- this.onUpdateExecutors.delete(e);
1525
- }
1526
- this.onUpdateCallbacks.delete(e);
1572
+ if (state?.onUpdateExecutors) for (const t of Array.from(state.onUpdateExecutors.values())) await this.release(t, true);
1527
1573
  this.cache.delete(e);
1528
1574
  };
1529
1575
  return Promised.create(coreRelease());
@@ -1538,28 +1584,22 @@ var BaseScope = class BaseScope {
1538
1584
  for (const current of currents) await this.release(current, true);
1539
1585
  this.disposed = true;
1540
1586
  this.cache.clear();
1541
- this.cleanups.clear();
1542
- this.onUpdateCallbacks.clear();
1543
- this.onUpdateExecutors.clear();
1544
1587
  this.onEvents.change.clear();
1545
1588
  this.onEvents.release.clear();
1546
1589
  this.onEvents.error.clear();
1547
- this.onErrors.clear();
1548
- this.resolutionChain.clear();
1549
1590
  })());
1550
1591
  }
1551
1592
  onUpdate(e, cb) {
1552
1593
  this["~ensureNotDisposed"]();
1553
1594
  if (this.isDisposing) throw new Error("Cannot register update callback on a disposing scope");
1554
- const ou = this.onUpdateCallbacks.get(e) ?? /* @__PURE__ */ new Set();
1555
- this.onUpdateCallbacks.set(e, ou);
1556
- ou.add(cb);
1595
+ const state = this.getOrCreateState(e);
1596
+ this.ensureCallbacks(state).add(cb);
1557
1597
  return () => {
1558
1598
  this["~ensureNotDisposed"]();
1559
- const ou$1 = this.onUpdateCallbacks.get(e);
1560
- if (ou$1) {
1561
- ou$1.delete(cb);
1562
- if (ou$1.size === 0) this.onUpdateCallbacks.delete(e);
1599
+ const state$1 = this.cache.get(e);
1600
+ if (state$1?.onUpdateCallbacks) {
1601
+ state$1.onUpdateCallbacks.delete(cb);
1602
+ if (state$1.onUpdateCallbacks.size === 0) delete state$1.onUpdateCallbacks;
1563
1603
  }
1564
1604
  };
1565
1605
  }
@@ -1593,15 +1633,14 @@ var BaseScope = class BaseScope {
1593
1633
  }
1594
1634
  if (callback) {
1595
1635
  const executor = executorOrCallback;
1596
- const errorCallbacks = this.onErrors.get(executor) ?? /* @__PURE__ */ new Set();
1597
- this.onErrors.set(executor, errorCallbacks);
1598
- errorCallbacks.add(callback);
1636
+ const state = this.getOrCreateState(executor);
1637
+ this.ensureErrors(state).add(callback);
1599
1638
  return () => {
1600
1639
  this["~ensureNotDisposed"]();
1601
- const callbacks = this.onErrors.get(executor);
1602
- if (callbacks) {
1603
- callbacks.delete(callback);
1604
- if (callbacks.size === 0) this.onErrors.delete(executor);
1640
+ const state$1 = this.cache.get(executor);
1641
+ if (state$1?.onErrors) {
1642
+ state$1.onErrors.delete(callback);
1643
+ if (state$1.onErrors.size === 0) delete state$1.onErrors;
1605
1644
  }
1606
1645
  };
1607
1646
  }
@@ -1631,14 +1670,14 @@ var BaseScope = class BaseScope {
1631
1670
  scope: this,
1632
1671
  extensions: options.extensions,
1633
1672
  initialContext: options.initialContext,
1634
- meta: options.meta,
1673
+ tags: options.tags,
1635
1674
  details: true
1636
1675
  });
1637
1676
  return flow.execute(flow$1, input, {
1638
1677
  scope: this,
1639
1678
  extensions: options?.extensions,
1640
1679
  initialContext: options?.initialContext,
1641
- meta: options?.meta,
1680
+ tags: options?.tags,
1642
1681
  details: false
1643
1682
  });
1644
1683
  }
@@ -1725,39 +1764,45 @@ var MultiExecutorImpl = class {
1725
1764
  function createValidatedExecutor(option, key, createExecutorFn) {
1726
1765
  return createExecutorFn(validate(option.keySchema, key));
1727
1766
  }
1728
- function createMultiExecutor(option, poolId, keyPool, createNewExecutor, providerMetas) {
1767
+ function createMultiExecutor(option, poolId, keyPool, createNewExecutor, providerTags) {
1729
1768
  const impl = new MultiExecutorImpl(option, poolId, keyPool, createNewExecutor);
1730
- const provider = createExecutor((ctl) => impl.providerFactory(ctl), void 0, providerMetas);
1769
+ const provider = createExecutor((ctl) => impl.providerFactory(ctl), void 0, providerTags);
1731
1770
  const callableFn = (key) => impl.__call(key);
1732
1771
  return Object.assign(callableFn, provider, {
1733
1772
  release: (scope) => impl.release(scope),
1734
1773
  id: impl.id
1735
1774
  });
1736
1775
  }
1737
- function provide$1(option, valueFn, ...metas) {
1738
- const poolId = meta(Symbol(), custom());
1776
+ function provide$1(option, valueFn, ...tags) {
1777
+ const poolId = tag(custom(), {
1778
+ label: Symbol().toString(),
1779
+ default: null
1780
+ });
1739
1781
  const keyPool = /* @__PURE__ */ new Map();
1740
1782
  const createNewExecutor = (key) => {
1741
- return createValidatedExecutor(option, key, (validatedKey) => createExecutor((ctl) => valueFn(validatedKey, ctl), void 0, [poolId(void 0), ...metas]));
1783
+ return createValidatedExecutor(option, key, (validatedKey) => createExecutor((ctl) => valueFn(validatedKey, ctl), void 0, [poolId(null), ...tags]));
1742
1784
  };
1743
- return createMultiExecutor(option, poolId, keyPool, createNewExecutor, [poolId(void 0), ...metas]);
1785
+ return createMultiExecutor(option, poolId, keyPool, createNewExecutor, [poolId(null), ...tags]);
1744
1786
  }
1745
- function derive$1(option, valueFn, ...metas) {
1746
- const poolId = meta(Symbol(), custom());
1787
+ function derive$1(option, valueFn, ...tags) {
1788
+ const poolId = tag(custom(), {
1789
+ label: Symbol().toString(),
1790
+ default: null
1791
+ });
1747
1792
  const keyPool = /* @__PURE__ */ new Map();
1748
1793
  const createNewExecutor = (key) => {
1749
1794
  return createValidatedExecutor(option, key, (validatedKey) => {
1750
1795
  const factory = (dependencies, ctl) => valueFn(dependencies, validatedKey, ctl);
1751
1796
  const deps = option.dependencies;
1752
- return createExecutor(factory, deps, metas);
1797
+ return createExecutor(factory, deps, tags);
1753
1798
  });
1754
1799
  };
1755
- return createMultiExecutor(option, poolId, keyPool, createNewExecutor, metas);
1800
+ return createMultiExecutor(option, poolId, keyPool, createNewExecutor, tags);
1756
1801
  }
1757
1802
 
1758
1803
  //#endregion
1759
1804
  //#region src/index.ts
1760
- const name = meta("pumped-fn/name", custom());
1805
+ const name = tag(custom(), { label: "pumped-fn/name" });
1761
1806
 
1762
1807
  //#endregion
1763
1808
  exports.DependencyResolutionError = DependencyResolutionError;
@@ -1767,7 +1812,6 @@ exports.FlowError = FlowError;
1767
1812
  exports.FlowValidationError = FlowValidationError;
1768
1813
  exports.Promised = Promised;
1769
1814
  exports.SchemaError = SchemaError;
1770
- exports.accessor = accessor;
1771
1815
  exports.createScope = createScope;
1772
1816
  exports.custom = custom;
1773
1817
  exports.derive = derive;
@@ -1779,19 +1823,14 @@ Object.defineProperty(exports, 'errors', {
1779
1823
  });
1780
1824
  exports.executorSymbol = executorSymbol;
1781
1825
  exports.extension = extension;
1782
- exports.findValue = findValue;
1783
- exports.findValues = findValues;
1784
1826
  exports.flow = flow;
1785
1827
  exports.flowMeta = flowMeta;
1786
- exports.getValue = getValue;
1787
1828
  exports.isExecutor = isExecutor;
1788
1829
  exports.isLazyExecutor = isLazyExecutor;
1789
1830
  exports.isMainExecutor = isMainExecutor;
1790
1831
  exports.isPreset = isPreset;
1791
1832
  exports.isReactiveExecutor = isReactiveExecutor;
1792
1833
  exports.isStaticExecutor = isStaticExecutor;
1793
- exports.meta = meta;
1794
- exports.metaSymbol = metaSymbol;
1795
1834
  Object.defineProperty(exports, 'multi', {
1796
1835
  enumerable: true,
1797
1836
  get: function () {
@@ -1807,4 +1846,6 @@ Object.defineProperty(exports, 'standardSchema', {
1807
1846
  get: function () {
1808
1847
  return ssch_exports;
1809
1848
  }
1810
- });
1849
+ });
1850
+ exports.tag = tag;
1851
+ exports.tagSymbol = tagSymbol;