@pravosleva/reactive-engine 2.5.0-alpha.8 → 2.6.0-beta.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.
Files changed (66) hide show
  1. package/dist/angular/index.cjs +1 -1
  2. package/dist/angular/index.cjs.map +1 -1
  3. package/dist/angular/index.mjs +1 -1
  4. package/dist/core/core.advanced.optimization.test.d.ts +2 -0
  5. package/dist/core/core.advanced.optimization.test.d.ts.map +1 -0
  6. package/dist/core/core.d.ts +20 -8
  7. package/dist/core/core.d.ts.map +1 -1
  8. package/dist/core/core.logger.d.ts.map +1 -1
  9. package/dist/core/core.method.computed.d.ts.map +1 -1
  10. package/dist/core/core.method.reactive.d.ts +3 -0
  11. package/dist/core/core.method.reactive.d.ts.map +1 -1
  12. package/dist/core/core.method.resource.d.ts +13 -0
  13. package/dist/core/core.method.resource.d.ts.map +1 -0
  14. package/dist/core/core.method.signal.d.ts.map +1 -1
  15. package/dist/core/index.d.ts +1 -0
  16. package/dist/core/index.d.ts.map +1 -1
  17. package/dist/core/types.d.ts +2 -0
  18. package/dist/core/types.d.ts.map +1 -1
  19. package/dist/core.automatic.cjs +1 -1
  20. package/dist/core.automatic.cjs.map +1 -1
  21. package/dist/core.automatic.mjs +1 -1
  22. package/dist/core.cjs +1 -1
  23. package/dist/core.cjs.map +1 -1
  24. package/dist/core.global.cjs +1 -1
  25. package/dist/core.global.cjs.map +1 -1
  26. package/dist/core.global.mjs +1 -1
  27. package/dist/core.logger.cjs +2 -0
  28. package/dist/core.logger.cjs.map +1 -0
  29. package/dist/core.logger.mjs +51 -0
  30. package/dist/core.logger.mjs.map +1 -0
  31. package/dist/core.method.computed.cjs +1 -1
  32. package/dist/core.method.computed.cjs.map +1 -1
  33. package/dist/core.method.computed.mjs +71 -86
  34. package/dist/core.method.computed.mjs.map +1 -1
  35. package/dist/core.method.reactive.cjs +1 -1
  36. package/dist/core.method.reactive.cjs.map +1 -1
  37. package/dist/core.method.reactive.mjs +45 -104
  38. package/dist/core.method.reactive.mjs.map +1 -1
  39. package/dist/core.method.resource.cjs +2 -0
  40. package/dist/core.method.resource.cjs.map +1 -0
  41. package/dist/core.method.resource.mjs +143 -0
  42. package/dist/core.method.resource.mjs.map +1 -0
  43. package/dist/core.method.signal.cjs +1 -1
  44. package/dist/core.method.signal.cjs.map +1 -1
  45. package/dist/core.method.signal.mjs +67 -38
  46. package/dist/core.method.signal.mjs.map +1 -1
  47. package/dist/core.mjs +80 -107
  48. package/dist/core.mjs.map +1 -1
  49. package/dist/decorators/withThrottleComputed/withThrottleComputed.d.ts +1 -1
  50. package/dist/index.cjs +1 -1
  51. package/dist/index.mjs +1 -1
  52. package/dist/index2.cjs +1 -1
  53. package/dist/index2.mjs +5 -5
  54. package/dist/react/index.cjs +1 -1
  55. package/dist/react/index.cjs.map +1 -1
  56. package/dist/react/index.mjs +1 -1
  57. package/dist/reactive-engine.umd.js +13 -0
  58. package/dist/reactive-engine.umd.js.map +1 -0
  59. package/dist/vue/index.cjs +1 -1
  60. package/dist/vue/index.cjs.map +1 -1
  61. package/dist/vue/index.mjs +1 -1
  62. package/package.json +1 -1
  63. package/dist/core/core.advanced.reactive-framework-test-suite.p3.test.d.ts +0 -2
  64. package/dist/core/core.advanced.reactive-framework-test-suite.p3.test.d.ts.map +0 -1
  65. package/dist/reactive-engine@2.5.0-alpha.8.umd.js +0 -13
  66. package/dist/reactive-engine@2.5.0-alpha.8.umd.js.map +0 -1
@@ -0,0 +1,143 @@
1
+ import { getExtractedValues as e } from "./utils/getExtractedValues.mjs";
2
+ //#region src/core/core.method.resource.ts
3
+ function t(t, n, r, i) {
4
+ let a = i && typeof i == "object", o = a ? i.name || "unnamed_resource" : i || "unnamed_resource", s = a ? i : {}, c = s.resetDataOnSourceChange ?? !0, l = s.responseValidate, u = s.validateBeforeFetch, d = t.signal({
5
+ data: null,
6
+ loading: !0,
7
+ error: null,
8
+ isRetrying: !1
9
+ }, `[CORE_INTERNAL_SIGNAL=1]:resource:state:${o}`), f = (e) => {
10
+ t.log({
11
+ type: "resource",
12
+ label: o,
13
+ details: {
14
+ to: e,
15
+ from: d.value
16
+ }
17
+ }), d.value = e;
18
+ }, p = async (r, i, a = !1) => {
19
+ if (i.aborted) return;
20
+ if (s.validateBeforeFetch && s.validateBeforeFetch(r), u) {
21
+ let e = u(r);
22
+ if (e === !1 || typeof e == "string") {
23
+ if (i.aborted) return;
24
+ let n = typeof e == "string" ? e : "Pre-fetch validation failed for resource", r = a ? null : t.untrack(() => d.value.data);
25
+ f({
26
+ data: r,
27
+ loading: !1,
28
+ error: n,
29
+ isRetrying: !1
30
+ });
31
+ return;
32
+ }
33
+ }
34
+ let p = a && c ? null : t.untrack(() => d.value.data);
35
+ f({
36
+ data: p,
37
+ loading: !0,
38
+ error: null,
39
+ isRetrying: !1
40
+ });
41
+ for (let a = 0; a <= 0; a++) {
42
+ if (i.aborted) return;
43
+ let s = i;
44
+ try {
45
+ let e = await n(r, s);
46
+ if (i.aborted) return;
47
+ if (s.aborted) throw new DOMException("The operation timed out.", "TimeoutError");
48
+ if (l) {
49
+ let t = l(e);
50
+ if (t === !1 || typeof t == "string") {
51
+ if (i.aborted) return;
52
+ f({
53
+ data: null,
54
+ loading: !1,
55
+ error: typeof t == "string" ? t : "Validation failed",
56
+ isRetrying: !1
57
+ });
58
+ return;
59
+ }
60
+ }
61
+ if (i.aborted) return;
62
+ f({
63
+ data: e,
64
+ loading: !1,
65
+ error: null,
66
+ isRetrying: !1
67
+ });
68
+ return;
69
+ } catch (n) {
70
+ if (i.aborted || n.name === "AbortError" && i.aborted) return;
71
+ let r = n.name === "TimeoutError" || n.name === "AbortError" || n.message?.includes("timeout"), s = e({
72
+ tested: [n.message],
73
+ expectedKey: "THROW_CUSTOM_VALIDATION_ERROR_NO_RETRY",
74
+ valueType: "number"
75
+ })?.[0] === "1" || !1, c = s && e({
76
+ tested: [n.message],
77
+ expectedKey: "MESSAGE",
78
+ valueType: "string"
79
+ })?.[0] || "Custom validation error", l = s || n.name === "ValidationError";
80
+ if (a === 0 || l) {
81
+ if (i.aborted) return;
82
+ let e = r ? Error("Request timed out after 1000ms", { cause: n }) : s ? Error(c, { cause: n }) : n;
83
+ f({
84
+ data: null,
85
+ loading: !1,
86
+ error: e instanceof Error ? e.message : typeof e == "string" ? e : `typeof finalError is ${typeof e}`,
87
+ isRetrying: !1
88
+ });
89
+ return;
90
+ } else {
91
+ if (i.aborted) return;
92
+ let e = 1e3 * 2 ** a;
93
+ e = Math.min(e, 3e5);
94
+ let n = Math.random() * 200;
95
+ e += n, f({
96
+ data: d.value.data,
97
+ loading: !0,
98
+ error: null,
99
+ isRetrying: !0
100
+ }), console.warn(`[Resource Retry] "${o}" сбой по ${r ? "таймауту" : "ошибке сети"}. Попытка ${a + 1}/${a + 1}...`);
101
+ try {
102
+ if (await t.delay(e, i), i.aborted) return;
103
+ } catch {
104
+ return;
105
+ }
106
+ }
107
+ }
108
+ }
109
+ }, m = null, h = t.effect(() => {
110
+ let e = r ? r.value : void 0, n = new AbortController();
111
+ return m = n, t.untrack(() => {
112
+ p(e, n.signal, !0);
113
+ }), () => n.abort();
114
+ }, "[CORE_INTERNAL_SIGNAL=1]:effect");
115
+ return {
116
+ get data() {
117
+ return d.value.data;
118
+ },
119
+ get loading() {
120
+ return d.value.loading;
121
+ },
122
+ get error() {
123
+ return d.value.error;
124
+ },
125
+ get isRetrying() {
126
+ return d.value.isRetrying;
127
+ },
128
+ get value() {
129
+ return d.value;
130
+ },
131
+ refetch: () => {
132
+ m?.abort(), m = new AbortController(), p(r ? r.value : void 0, m.signal, !1);
133
+ },
134
+ subscribe: (e) => d.subscribe(e),
135
+ destroy: () => {
136
+ m?.abort(), m = null, typeof h == "function" && h(), d.destroy && d.destroy();
137
+ }
138
+ };
139
+ }
140
+ //#endregion
141
+ export { t as createResource };
142
+
143
+ //# sourceMappingURL=core.method.resource.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"core.method.resource.mjs","names":[],"sources":["../src/core/core.method.resource.ts"],"sourcesContent":["import { getExtractedValues } from '../utils/getExtractedValues'\nimport { Resource, ResourceOptions, ResourceState, Signal } from './types'\n\n// Контракт ядра движка для безопасных вызовов методов с дженериками\ninterface IReactiveEngine {\n signal<V>(initialValue: V, optionsOrName?: any): Signal<V>;\n effect(fn: () => any, name?: string): () => void;\n untrack<V>(fn: () => V): V;\n log(params: any): void;\n delay(ms: number, signal: AbortSignal): Promise<void>;\n}\n\nexport function createResource<T, S = void>(\n engine: IReactiveEngine,\n fetcher: (source: S, signal: AbortSignal) => Promise<T>,\n source?: { value: S },\n optionsOrName?: string | ResourceOptions<T, S>\n): Resource<T> {\n const isOptionsObject = optionsOrName && typeof optionsOrName === 'object'\n const resourceSignalName = isOptionsObject\n ? ((optionsOrName as ResourceOptions<T, S>).name || 'unnamed_resource')\n : (optionsOrName as string) || 'unnamed_resource'\n\n const options: Partial<ResourceOptions<T, S>> = isOptionsObject\n ? (optionsOrName as ResourceOptions<T, S>)\n : {}\n\n const resetDataOnSourceChange = options.resetDataOnSourceChange ?? true\n const responseValidate = options.responseValidate\n const validateBeforeFetch = options.validateBeforeFetch\n const retryCount = 0\n const baseDelay = 1000\n const useExponential = true\n const maxRetryDelay = 1000 * 60 * 5\n const timeoutMs = 1000\n\n // Вызов скомпилируется успешно, так как метод signal теперь строго описан в интерфейсе\n const state = engine.signal<ResourceState<T>>(\n { data: null, loading: true, error: null, isRetrying: false },\n `[CORE_INTERNAL_SIGNAL=1]:resource:state:${resourceSignalName}`\n )\n\n const updateResourceState = (nextState: ResourceState<T>) => {\n engine.log({ type: 'resource', label: resourceSignalName, details: { to: nextState, from: state.value } })\n state.value = nextState\n }\n\n const load = async (sValue: S, effectSignal: AbortSignal, isSourceChange = false) => {\n if (effectSignal.aborted) return\n const isValid = options.validateBeforeFetch ? options.validateBeforeFetch(sValue) : true\n\n if (validateBeforeFetch) {\n const preValidationResult = validateBeforeFetch(sValue)\n if (preValidationResult === false || typeof preValidationResult === 'string') {\n if (effectSignal.aborted) return\n const errorMsg = typeof preValidationResult === 'string'\n ? preValidationResult\n : 'Pre-fetch validation failed for resource'\n\n const currentData = isSourceChange ? null : engine.untrack(() => state.value.data)\n updateResourceState({ data: currentData, loading: false, error: errorMsg, isRetrying: false })\n return\n }\n }\n const shouldClear = isSourceChange && resetDataOnSourceChange\n const currentData = shouldClear ? null : engine.untrack(() => state.value.data)\n updateResourceState({ data: currentData, loading: true, error: null, isRetrying: false })\n for (let attempt = 0; attempt <= retryCount; attempt++) {\n if (effectSignal.aborted) return\n let combinedSignal = effectSignal\n try {\n const data = await fetcher(sValue, combinedSignal)\n if (effectSignal.aborted) return\n if (combinedSignal.aborted) {\n throw new DOMException('The operation timed out.', 'TimeoutError')\n }\n if (responseValidate) {\n const validationResult = responseValidate(data)\n if (validationResult === false || typeof validationResult === 'string') {\n if (effectSignal.aborted) return\n const errorMsg = typeof validationResult === 'string' ? validationResult : 'Validation failed'\n updateResourceState({ data: null, loading: false, error: errorMsg, isRetrying: false })\n return\n }\n }\n if (effectSignal.aborted) return\n updateResourceState({ data, loading: false, error: null, isRetrying: false })\n return\n } catch (e: unknown) {\n if (effectSignal.aborted || ((e as Error).name === 'AbortError' && effectSignal.aborted)) return\n const isTimeout = (e as Error).name === 'TimeoutError' || (e as Error).name === 'AbortError' || (e as Error).message?.includes('timeout')\n const isCustomValidationError = getExtractedValues({\n tested: [(e as Error).message], expectedKey: 'THROW_CUSTOM_VALIDATION_ERROR_NO_RETRY', valueType: 'number',\n })?.[0] === '1' || false\n const __defaultCustomValidationErrorMessage = 'Custom validation error'\n let customValidationErrorMessage: string = isCustomValidationError\n ? (getExtractedValues({\n tested: [(e as Error).message], expectedKey: 'MESSAGE', valueType: 'string',\n })?.[0] || __defaultCustomValidationErrorMessage)\n : __defaultCustomValidationErrorMessage\n const isFetchBodyValidationError = isCustomValidationError || (e as Error).name === 'ValidationError'\n if (attempt === retryCount || isFetchBodyValidationError) {\n if (effectSignal.aborted) return\n const finalError = isTimeout\n ? new Error(`Request timed out after ${timeoutMs}ms`, { cause: e })\n : isCustomValidationError\n ? new Error(customValidationErrorMessage, { cause: e })\n : e\n\n updateResourceState({\n data: null, loading: false,\n error: finalError instanceof Error ? finalError.message : typeof finalError === 'string' ? finalError : `typeof finalError is ${typeof finalError}`,\n isRetrying: false,\n })\n return\n } else {\n if (effectSignal.aborted) return\n let currentDelay = useExponential ? baseDelay * Math.pow(2, attempt) : baseDelay\n currentDelay = Math.min(currentDelay, maxRetryDelay)\n const jitter = Math.random() * 200\n currentDelay = currentDelay + jitter\n updateResourceState({ data: state.value.data, loading: true, error: null, isRetrying: true })\n const logReason = isTimeout ? 'таймауту' : 'ошибке сети'\n console.warn(`[Resource Retry] \"${resourceSignalName}\" сбой по ${logReason}. Попытка ${attempt + 1}/${retryCount > 0 ? retryCount + 1 : attempt + 1}...`)\n\n try {\n await engine.delay(currentDelay, effectSignal)\n if (effectSignal.aborted) return\n } catch (delayError) {\n return\n }\n }\n }\n }\n }\n\n let activeEffectController: AbortController | null = null\n\n const disposeInternalEffect = engine.effect(() => {\n const sValue = source ? source.value : undefined as S\n const effectController = new AbortController()\n activeEffectController = effectController\n\n engine.untrack(() => {\n load(sValue as S, effectController.signal, true)\n })\n\n return () => effectController.abort()\n }, '[CORE_INTERNAL_SIGNAL=1]:effect')\n\n return {\n get data() { return state.value.data },\n get loading() { return state.value.loading },\n get error() { return state.value.error },\n get isRetrying() { return state.value.isRetrying },\n get value() { return state.value },\n refetch: () => {\n activeEffectController?.abort()\n activeEffectController = new AbortController()\n load(source ? source.value : undefined as S, activeEffectController.signal, false)\n },\n subscribe: (cb: (val: ResourceState<T>) => void) => state.subscribe(cb),\n destroy: () => {\n activeEffectController?.abort()\n activeEffectController = null\n if (typeof disposeInternalEffect === 'function') {\n disposeInternalEffect()\n }\n if ((state as any).destroy) {\n (state as any).destroy()\n }\n }\n } as any\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- const e=require("./utils/getExtractedValues.cjs");function t(t,n,r){let i=n,a=0,o=typeof r==`string`?r:r?.name;o&&e.getExtractedValues({tested:[o],expectedKey:`CORE_INTERNAL_SIGNAL`,valueType:`number`})?.[0];let s=new Set,c=!1,l=n,u={type:`signal`,get version(){return a},subscribers:s},d=(e=2)=>{for(let n of s){let r=n._node||n;if(r.type===`effect`)r.isDirty=!0,t.scheduleEffect(n);else if(r.type===`computed`)r.markDirty&&r.markDirty(e);else if(typeof n==`function`)try{n(i)}catch(e){console.error(e)}else if(n&&typeof n.run==`function`)try{n.run()}catch(e){console.error(e)}}},f={get value(){let e=t.activeConsumer;if(e){s.add(t.activeConsumer),t.activeConsumer.dependencies.add(f);let n=e._node||e;n.depth!==void 0&&n.depth===1&&(n.depth=2),e.activeRunId!==void 0&&(f._lastSeenInRunId=e.activeRunId)}return i},set value(e){if(!(Object.is(i,e)&&!(i===e&&typeof i==`object`&&i))){if(r&&typeof r==`object`&&r.validate){let t=r.validate(e);if(t!==!0){console.error(typeof t==`string`?t:`[Validation Error]`);return}}if(t.batchDepth>0){c||(c=!0,l=i),i=e,f.hasBatchValue=!0,d(1),t.batchedSignals.add(f);return}i=e,a++,t.epoch++,d(2),t.batchDepth===0&&t.flushEffects()}},get version(){return a},type:`signal`,subscribe(e){return s.add(e),e(i),()=>{s.delete(e)}},_applyBatchValue:()=>c&&(!Object.is(l,i)||typeof i==`object`&&i)?(a++,!0):!1,_flushBatch:(e,n)=>{c&&(e?(n||t.epoch++,d(1)):d(0),c=!1,f.hasBatchValue=!1,l=i)}};return f._node=u,f.subscribers=s,f}exports.createSignal=t;
1
+ const e=require("./utils/getExtractedValues.cjs");function t(t,n,r){let i=n,a=0,o=typeof r==`string`?r:r?.name,s=!!o&&e.getExtractedValues({tested:[o],expectedKey:`CORE_INTERNAL_SIGNAL`,valueType:`number`})?.[0]===`1`||!1,c=new Set,l=!1,u=n,d={type:`signal`,get version(){return a},subscribers:c},f=()=>{for(let e of c){let n=e._node||e;if(n.type===`effect`)n.isDirty=!0,t.scheduleEffect(e);else if(n.type===`computed`)n.markDirty&&n.markDirty(2);else if(typeof e==`function`)try{e(i)}catch(e){console.error(e)}else if(e&&typeof e.run==`function`)try{e.run()}catch(e){console.error(e)}}},p={get value(){let e=t.activeConsumer;return e&&(c.add(t.activeConsumer),t.activeConsumer.dependencies.add(p),e.activeRunId!==void 0&&(p._lastSeenInRunId=e.activeRunId)),i},set value(e){if(Object.is(i,e)&&!(i===e&&typeof i==`object`&&i))return;if(r&&typeof r==`object`&&r.validate){let t=r.validate(e);if(t!==!0){console.error(typeof t==`string`?t:`[Validation Error]`);return}}if(t.batchDepth>0){l||(l=!0,u=i),i=e,t.batchedSignals.add(p);return}let n=i;i=e,a++,t.epoch++,t.log({type:`signal`,label:o||`signal`,details:{from:n,to:e},isInternalCoreSignal:s}),f(),t.batchDepth===0&&t.flushEffects()},get version(){return a},type:`signal`,subscribe(e){return c.add(e),e(i),()=>{c.delete(e)}},_flushBatch:()=>{if(l){if(!Object.is(u,i)||typeof i==`object`&&i){a++,t.epoch++,t.log({type:`signal`,label:o||`signal_batched`,details:{from:u,to:i},isInternalCoreSignal:s});for(let e of c){let n=e._node||e;if(n.type===`effect`)n.isDirty=!0,t.scheduleEffect(e);else if(n.markDirty)n.markDirty(2);else if(typeof e==`function`)try{e(i)}catch(e){console.error(e)}}}l=!1,u=i}},get hasBatchValue(){return l},destroy:()=>{c&&c.clear(),t.batchedSignals&&t.batchedSignals.delete(p),l=!1,i=void 0,u=void 0}};return p._node=d,p.subscribers=c,p}exports.createSignal=t;
2
2
  //# sourceMappingURL=core.method.signal.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"core.method.signal.cjs","names":[],"sources":["../src/core/core.method.signal.ts"],"sourcesContent":["import { getExtractedValues } from '../utils/getExtractedValues'\nimport { Signal, SignalOptions } from './types'\n\nexport function createSignal<T>(\n engine: any,\n initialValue: T,\n optionsOrName?: SignalOptions<T> | string\n): Signal<T> {\n let value = initialValue\n let version = 0\n let name = typeof optionsOrName === 'string' ? optionsOrName : optionsOrName?.name\n\n const extracted = !!name ? getExtractedValues({\n tested: [name],\n expectedKey: 'CORE_INTERNAL_SIGNAL',\n valueType: 'number',\n })?.[0] : null\n const isInternalCoreSignal = extracted && extracted === '1'\n\n const subscribers = new Set<any>()\n\n let hasBatchValue = false\n let batchInitialValue: T = initialValue\n\n const signalNode = {\n type: 'signal',\n get version() { return version },\n subscribers\n }\n\n const notifySubscribers = (parentState: number = 2) => {\n for (const sub of subscribers) {\n const rawSub = sub._node || sub\n if (rawSub.type === 'effect') {\n rawSub.isDirty = true\n engine.scheduleEffect(sub)\n } else if (rawSub.type === 'computed') {\n if (rawSub.markDirty) rawSub.markDirty(parentState)\n } else {\n if (typeof sub === 'function') {\n try { sub(value) } catch (err) { console.error(err) }\n } else if (sub && typeof sub.run === 'function') {\n try { sub.run() } catch (err) { console.error(err) }\n }\n }\n }\n }\n\n const signalInstance: Signal<T> = {\n get value() {\n const consumer = engine.activeConsumer\n if (consumer) {\n subscribers.add(engine.activeConsumer)\n engine.activeConsumer.dependencies.add(signalInstance)\n\n const consumerRaw = consumer._node || consumer\n if (consumerRaw.depth !== undefined && consumerRaw.depth === 1) {\n consumerRaw.depth = 2\n }\n\n if (consumer.activeRunId !== undefined) {\n (signalInstance as any)._lastSeenInRunId = consumer.activeRunId\n }\n }\n return value\n },\n\n set value(newValue: T) {\n const isObjectKick = value === newValue && value !== null && typeof value === 'object'\n if (Object.is(value, newValue) && !isObjectKick) return\n\n if (optionsOrName && typeof optionsOrName === 'object' && optionsOrName.validate) {\n const validation = optionsOrName.validate(newValue)\n if (validation !== true) {\n console.error(typeof validation === 'string' ? validation : '[Validation Error]')\n return\n }\n }\n\n if (engine.batchDepth > 0) {\n if (!hasBatchValue) {\n hasBatchValue = true\n batchInitialValue = value\n }\n value = newValue\n\n ;(signalInstance as any).hasBatchValue = true\n notifySubscribers(1) // Мягкая маркировка CHECK (1) интра-ран чтений батча\n\n engine.batchedSignals.add(signalInstance)\n return\n }\n\n const oldValue = value\n value = newValue\n\n version++\n engine.epoch++\n\n notifySubscribers(2)\n if (engine.batchDepth === 0) engine.flushEffects()\n },\n\n get version() { return version },\n type: 'signal',\n\n subscribe(cb: (val: T) => void) {\n subscribers.add(cb)\n cb(value)\n return () => { subscribers.delete(cb) }\n },\n\n // ⚛️ ФАЗА 1: Чистая фиксация новых версий\n _applyBatchValue: () => {\n if (!hasBatchValue) return false\n const wasChanged = !Object.is(batchInitialValue, value) || (value !== null && typeof value === 'object')\n if (wasChanged) {\n version++\n return true\n }\n return false\n },\n\n // ⚛️ ФАЗА 2: Чистый атомарный push-уведомитель\n _flushBatch: (wasChanged: boolean, isAlreadyEpochShifted?: boolean) => {\n if (!hasBatchValue) return\n\n if (wasChanged) {\n if (!isAlreadyEpochShifted) {\n engine.epoch++\n }\n // ⚛️ КAНОНИЧЕСКИЙ БАТЧИНГ: Переводим в CHECK (1) вместо DIRTY (2).\n // Это блокирует веерные перезапуски сирот и алмазов на выходе из батча!\n notifySubscribers(1)\n } else {\n notifySubscribers(0)\n }\n\n hasBatchValue = false\n ;(signalInstance as any).hasBatchValue = false\n batchInitialValue = value\n }\n\n } as any\n\n ;(signalInstance as any)._node = signalNode\n ;(signalInstance as any).subscribers = subscribers\n return signalInstance\n}\n"],"mappings":"kDAGA,SAAgB,EACd,EACA,EACA,EACW,CACX,IAAI,EAAQ,EACR,EAAU,EACV,EAAO,OAAO,GAAkB,SAAW,EAAgB,GAAe,KAE5D,GAAS,EAAA,mBAAmB,CAC5C,OAAQ,CAAC,CAAI,EACb,YAAa,uBACb,UAAW,QACb,CAAC,CAAC,GAAG,GAGL,IAAM,EAAc,IAAI,IAEpB,EAAgB,GAChB,EAAuB,EAErB,EAAa,CACjB,KAAM,SACN,IAAI,SAAU,CAAE,OAAO,CAAQ,EAC/B,aACF,EAEM,GAAqB,EAAsB,IAAM,CACrD,IAAK,IAAM,KAAO,EAAa,CAC7B,IAAM,EAAS,EAAI,OAAS,EAC5B,GAAI,EAAO,OAAS,SAClB,EAAO,QAAU,GACjB,EAAO,eAAe,CAAG,OACpB,GAAI,EAAO,OAAS,WACrB,EAAO,WAAW,EAAO,UAAU,CAAW,OAElD,GAAI,OAAO,GAAQ,WACjB,GAAI,CAAE,EAAI,CAAK,CAAE,OAAS,EAAK,CAAE,QAAQ,MAAM,CAAG,CAAE,MAC/C,GAAI,GAAO,OAAO,EAAI,KAAQ,WACnC,GAAI,CAAE,EAAI,IAAI,CAAE,OAAS,EAAK,CAAE,QAAQ,MAAM,CAAG,CAAE,CAGzD,CACF,EAEM,EAA4B,CAChC,IAAI,OAAQ,CACV,IAAM,EAAW,EAAO,eACxB,GAAI,EAAU,CACZ,EAAY,IAAI,EAAO,cAAc,EACrC,EAAO,eAAe,aAAa,IAAI,CAAc,EAErD,IAAM,EAAc,EAAS,OAAS,EAClC,EAAY,QAAU,IAAA,IAAa,EAAY,QAAU,IAC3D,EAAY,MAAQ,GAGlB,EAAS,cAAgB,IAAA,KAC3B,EAAwB,iBAAmB,EAAS,YAExD,CACA,OAAO,CACT,EAEA,IAAI,MAAM,EAAa,CAEjB,YAAO,GAAG,EAAO,CAAQ,GAAK,EADb,IAAU,GAA8B,OAAO,GAAU,UAAnC,IAG3C,IAAI,GAAiB,OAAO,GAAkB,UAAY,EAAc,SAAU,CAChF,IAAM,EAAa,EAAc,SAAS,CAAQ,EAClD,GAAI,IAAe,GAAM,CACvB,QAAQ,MAAM,OAAO,GAAe,SAAW,EAAa,oBAAoB,EAChF,MACF,CACF,CAEA,GAAI,EAAO,WAAa,EAAG,CACpB,IACH,EAAgB,GAChB,EAAoB,GAEtB,EAAQ,EAEP,EAAwB,cAAgB,GACzC,EAAkB,CAAC,EAEnB,EAAO,eAAe,IAAI,CAAc,EACxC,MACF,CAGA,EAAQ,EAER,IACA,EAAO,QAEP,EAAkB,CAAC,EACf,EAAO,aAAe,GAAG,EAAO,aAAa,CAvBjD,CAwBF,EAEA,IAAI,SAAU,CAAE,OAAO,CAAQ,EAC/B,KAAM,SAEN,UAAU,EAAsB,CAG9B,OAFA,EAAY,IAAI,CAAE,EAClB,EAAG,CAAK,MACK,CAAE,EAAY,OAAO,CAAE,CAAE,CACxC,EAGA,qBACO,IACc,CAAC,OAAO,GAAG,EAAmB,CAAK,GAAwB,OAAO,GAAU,UAAnC,IAE1D,IACO,IAEF,GAIT,aAAc,EAAqB,IAAoC,CAChE,IAED,GACG,GACH,EAAO,QAIT,EAAkB,CAAC,GAEnB,EAAkB,CAAC,EAGrB,EAAgB,GACf,EAAwB,cAAgB,GACzC,EAAoB,EACtB,CAEF,EAIA,MAFC,GAAwB,MAAQ,EAChC,EAAwB,YAAc,EAChC,CACT"}
1
+ {"version":3,"file":"core.method.signal.cjs","names":[],"sources":["../src/core/core.method.signal.ts"],"sourcesContent":["import { getExtractedValues } from '../utils/getExtractedValues'\nimport { Signal, SignalOptions } from './types'\n\nexport function createSignal<T>(\n engine: any,\n initialValue: T,\n optionsOrName?: SignalOptions<T> | string\n): Signal<T> {\n let value = initialValue\n let version = 0\n let name = typeof optionsOrName === 'string' ? optionsOrName : optionsOrName?.name\n const isInternalCoreSignal = !!name && getExtractedValues({\n tested: [name],\n expectedKey: 'CORE_INTERNAL_SIGNAL',\n valueType: 'number',\n })?.[0] === '1' || false\n const subscribers = new Set<any>()\n\n let hasBatchValue = false\n let batchInitialValue: T = initialValue\n\n const signalNode = {\n type: 'signal',\n get version() { return version },\n subscribers\n }\n\n const notifySubscribers = () => {\n for (const sub of subscribers) {\n const rawSub = sub._node || sub\n if (rawSub.type === 'effect') {\n rawSub.isDirty = true\n engine.scheduleEffect(sub)\n } else if (rawSub.type === 'computed') {\n if (rawSub.markDirty) rawSub.markDirty(2)\n } else {\n if (typeof sub === 'function') {\n try { sub(value) } catch (err) { console.error(err) }\n } else if (sub && typeof sub.run === 'function') {\n try { sub.run() } catch (err) { console.error(err) }\n }\n }\n }\n }\n\n const signalInstance: Signal<T> = {\n get value() {\n const consumer = engine.activeConsumer\n if (consumer) {\n subscribers.add(engine.activeConsumer)\n engine.activeConsumer.dependencies.add(signalInstance)\n\n if (consumer.activeRunId !== undefined) {\n (signalInstance as any)._lastSeenInRunId = consumer.activeRunId\n }\n }\n return value\n },\n\n set value(newValue: T) {\n const isObjectKick = value === newValue && value !== null && typeof value === 'object'\n if (Object.is(value, newValue) && !isObjectKick) return\n\n if (optionsOrName && typeof optionsOrName === 'object' && optionsOrName.validate) {\n const validation = optionsOrName.validate(newValue)\n if (validation !== true) {\n console.error(typeof validation === 'string' ? validation : '[Validation Error]')\n return\n }\n }\n\n if (engine.batchDepth > 0) {\n if (!hasBatchValue) {\n hasBatchValue = true\n batchInitialValue = value\n }\n value = newValue\n engine.batchedSignals.add(signalInstance)\n return\n }\n\n const oldValue = value\n value = newValue\n\n version++\n engine.epoch++\n\n engine.log({\n type: 'signal',\n label: name || 'signal',\n details: { from: oldValue, to: newValue },\n isInternalCoreSignal\n })\n\n notifySubscribers()\n if (engine.batchDepth === 0) engine.flushEffects()\n },\n\n get version() { return version },\n type: 'signal',\n\n subscribe(cb: (val: T) => void) {\n subscribers.add(cb)\n cb(value)\n return () => { subscribers.delete(cb) }\n },\n\n _flushBatch: () => {\n if (!hasBatchValue) return\n\n const wasChanged = !Object.is(batchInitialValue, value) || (value !== null && typeof value === 'object')\n\n if (wasChanged) {\n version++\n engine.epoch++\n\n engine.log({\n type: 'signal',\n label: name || 'signal_batched',\n details: { from: batchInitialValue, to: value },\n isInternalCoreSignal\n })\n\n for (const sub of subscribers) {\n const rawSub = sub._node || sub\n if (rawSub.type === 'effect') {\n rawSub.isDirty = true\n engine.scheduleEffect(sub)\n } else if (rawSub.markDirty) {\n rawSub.markDirty(2)\n } else if (typeof sub === 'function') {\n try { sub(value) } catch (err) { console.error(err) }\n }\n }\n }\n\n hasBatchValue = false\n batchInitialValue = value\n },\n\n get hasBatchValue() { return hasBatchValue },\n\n // ⚛️ ФИКС ДЛЯ РЕЛИЗА 2.5.0: Метод тотальной деструкции сигнала\n destroy: () => {\n if (subscribers) {\n subscribers.clear()\n }\n if (engine.batchedSignals) {\n engine.batchedSignals.delete(signalInstance)\n }\n hasBatchValue = false\n // Помогаем GC, убирая ссылки на тяжелые объекты\n value = undefined as any\n batchInitialValue = undefined as any\n }\n } as any\n\n ;(signalInstance as any)._node = signalNode\n ;(signalInstance as any).subscribers = subscribers\n return signalInstance\n}\n"],"mappings":"kDAGA,SAAgB,EACd,EACA,EACA,EACW,CACX,IAAI,EAAQ,EACR,EAAU,EACV,EAAO,OAAO,GAAkB,SAAW,EAAgB,GAAe,KACxE,EAAuB,CAAC,CAAC,GAAQ,EAAA,mBAAmB,CACxD,OAAQ,CAAC,CAAI,EACb,YAAa,uBACb,UAAW,QACb,CAAC,CAAC,GAAG,KAAO,KAAO,GACb,EAAc,IAAI,IAEpB,EAAgB,GAChB,EAAuB,EAErB,EAAa,CACjB,KAAM,SACN,IAAI,SAAU,CAAE,OAAO,CAAQ,EAC/B,aACF,EAEM,MAA0B,CAC9B,IAAK,IAAM,KAAO,EAAa,CAC7B,IAAM,EAAS,EAAI,OAAS,EAC5B,GAAI,EAAO,OAAS,SAClB,EAAO,QAAU,GACjB,EAAO,eAAe,CAAG,OACpB,GAAI,EAAO,OAAS,WACrB,EAAO,WAAW,EAAO,UAAU,CAAC,OAExC,GAAI,OAAO,GAAQ,WACjB,GAAI,CAAE,EAAI,CAAK,CAAE,OAAS,EAAK,CAAE,QAAQ,MAAM,CAAG,CAAE,MAC/C,GAAI,GAAO,OAAO,EAAI,KAAQ,WACnC,GAAI,CAAE,EAAI,IAAI,CAAE,OAAS,EAAK,CAAE,QAAQ,MAAM,CAAG,CAAE,CAGzD,CACF,EAEM,EAA4B,CAChC,IAAI,OAAQ,CACV,IAAM,EAAW,EAAO,eASxB,OARI,IACF,EAAY,IAAI,EAAO,cAAc,EACrC,EAAO,eAAe,aAAa,IAAI,CAAc,EAEjD,EAAS,cAAgB,IAAA,KAC3B,EAAwB,iBAAmB,EAAS,cAGjD,CACT,EAEA,IAAI,MAAM,EAAa,CAErB,GAAI,OAAO,GAAG,EAAO,CAAQ,GAAK,EADb,IAAU,GAA8B,OAAO,GAAU,UAAnC,GACM,OAEjD,GAAI,GAAiB,OAAO,GAAkB,UAAY,EAAc,SAAU,CAChF,IAAM,EAAa,EAAc,SAAS,CAAQ,EAClD,GAAI,IAAe,GAAM,CACvB,QAAQ,MAAM,OAAO,GAAe,SAAW,EAAa,oBAAoB,EAChF,MACF,CACF,CAEA,GAAI,EAAO,WAAa,EAAG,CACpB,IACH,EAAgB,GAChB,EAAoB,GAEtB,EAAQ,EACR,EAAO,eAAe,IAAI,CAAc,EACxC,MACF,CAEA,IAAM,EAAW,EACjB,EAAQ,EAER,IACA,EAAO,QAEP,EAAO,IAAI,CACT,KAAM,SACN,MAAO,GAAQ,SACf,QAAS,CAAE,KAAM,EAAU,GAAI,CAAS,EACxC,sBACF,CAAC,EAED,EAAkB,EACd,EAAO,aAAe,GAAG,EAAO,aAAa,CACnD,EAEA,IAAI,SAAU,CAAE,OAAO,CAAQ,EAC/B,KAAM,SAEN,UAAU,EAAsB,CAG9B,OAFA,EAAY,IAAI,CAAE,EAClB,EAAG,CAAK,MACK,CAAE,EAAY,OAAO,CAAE,CAAE,CACxC,EAEA,gBAAmB,CACZ,KAIL,IAFmB,CAAC,OAAO,GAAG,EAAmB,CAAK,GAAwB,OAAO,GAAU,UAAnC,EAE5C,CACd,IACA,EAAO,QAEP,EAAO,IAAI,CACT,KAAM,SACN,MAAO,GAAQ,iBACf,QAAS,CAAE,KAAM,EAAmB,GAAI,CAAM,EAC9C,sBACF,CAAC,EAED,IAAK,IAAM,KAAO,EAAa,CAC7B,IAAM,EAAS,EAAI,OAAS,EAC5B,GAAI,EAAO,OAAS,SAClB,EAAO,QAAU,GACjB,EAAO,eAAe,CAAG,OACpB,GAAI,EAAO,UAChB,EAAO,UAAU,CAAC,OACb,GAAI,OAAO,GAAQ,WACxB,GAAI,CAAE,EAAI,CAAK,CAAE,OAAS,EAAK,CAAE,QAAQ,MAAM,CAAG,CAAE,CAExD,CACF,CAEA,EAAgB,GAChB,EAAoB,CAHpB,CAIF,EAEA,IAAI,eAAgB,CAAE,OAAO,CAAc,EAG3C,YAAe,CACT,GACF,EAAY,MAAM,EAEhB,EAAO,gBACT,EAAO,eAAe,OAAO,CAAc,EAE7C,EAAgB,GAEhB,EAAQ,IAAA,GACR,EAAoB,IAAA,EACtB,CACF,EAIA,MAFC,GAAwB,MAAQ,EAChC,EAAwB,YAAc,EAChC,CACT"}
@@ -1,75 +1,104 @@
1
1
  import { getExtractedValues as e } from "./utils/getExtractedValues.mjs";
2
2
  //#region src/core/core.method.signal.ts
3
3
  function t(t, n, r) {
4
- let i = n, a = 0, o = typeof r == "string" ? r : r?.name;
5
- o && e({
4
+ let i = n, a = 0, o = typeof r == "string" ? r : r?.name, s = !!o && e({
6
5
  tested: [o],
7
6
  expectedKey: "CORE_INTERNAL_SIGNAL",
8
7
  valueType: "number"
9
- })?.[0];
10
- let s = /* @__PURE__ */ new Set(), c = !1, l = n, u = {
8
+ })?.[0] === "1" || !1, c = /* @__PURE__ */ new Set(), l = !1, u = n, d = {
11
9
  type: "signal",
12
10
  get version() {
13
11
  return a;
14
12
  },
15
- subscribers: s
16
- }, d = (e = 2) => {
17
- for (let n of s) {
18
- let r = n._node || n;
19
- if (r.type === "effect") r.isDirty = !0, t.scheduleEffect(n);
20
- else if (r.type === "computed") r.markDirty && r.markDirty(e);
21
- else if (typeof n == "function") try {
22
- n(i);
13
+ subscribers: c
14
+ }, f = () => {
15
+ for (let e of c) {
16
+ let n = e._node || e;
17
+ if (n.type === "effect") n.isDirty = !0, t.scheduleEffect(e);
18
+ else if (n.type === "computed") n.markDirty && n.markDirty(2);
19
+ else if (typeof e == "function") try {
20
+ e(i);
23
21
  } catch (e) {
24
22
  console.error(e);
25
23
  }
26
- else if (n && typeof n.run == "function") try {
27
- n.run();
24
+ else if (e && typeof e.run == "function") try {
25
+ e.run();
28
26
  } catch (e) {
29
27
  console.error(e);
30
28
  }
31
29
  }
32
- }, f = {
30
+ }, p = {
33
31
  get value() {
34
32
  let e = t.activeConsumer;
35
- if (e) {
36
- s.add(t.activeConsumer), t.activeConsumer.dependencies.add(f);
37
- let n = e._node || e;
38
- n.depth !== void 0 && n.depth === 1 && (n.depth = 2), e.activeRunId !== void 0 && (f._lastSeenInRunId = e.activeRunId);
39
- }
40
- return i;
33
+ return e && (c.add(t.activeConsumer), t.activeConsumer.dependencies.add(p), e.activeRunId !== void 0 && (p._lastSeenInRunId = e.activeRunId)), i;
41
34
  },
42
35
  set value(e) {
43
- if (!(Object.is(i, e) && !(i === e && typeof i == "object" && i))) {
44
- if (r && typeof r == "object" && r.validate) {
45
- let t = r.validate(e);
46
- if (t !== !0) {
47
- console.error(typeof t == "string" ? t : "[Validation Error]");
48
- return;
49
- }
50
- }
51
- if (t.batchDepth > 0) {
52
- c || (c = !0, l = i), i = e, f.hasBatchValue = !0, d(1), t.batchedSignals.add(f);
36
+ if (Object.is(i, e) && !(i === e && typeof i == "object" && i)) return;
37
+ if (r && typeof r == "object" && r.validate) {
38
+ let t = r.validate(e);
39
+ if (t !== !0) {
40
+ console.error(typeof t == "string" ? t : "[Validation Error]");
53
41
  return;
54
42
  }
55
- i = e, a++, t.epoch++, d(2), t.batchDepth === 0 && t.flushEffects();
56
43
  }
44
+ if (t.batchDepth > 0) {
45
+ l || (l = !0, u = i), i = e, t.batchedSignals.add(p);
46
+ return;
47
+ }
48
+ let n = i;
49
+ i = e, a++, t.epoch++, t.log({
50
+ type: "signal",
51
+ label: o || "signal",
52
+ details: {
53
+ from: n,
54
+ to: e
55
+ },
56
+ isInternalCoreSignal: s
57
+ }), f(), t.batchDepth === 0 && t.flushEffects();
57
58
  },
58
59
  get version() {
59
60
  return a;
60
61
  },
61
62
  type: "signal",
62
63
  subscribe(e) {
63
- return s.add(e), e(i), () => {
64
- s.delete(e);
64
+ return c.add(e), e(i), () => {
65
+ c.delete(e);
65
66
  };
66
67
  },
67
- _applyBatchValue: () => c && (!Object.is(l, i) || typeof i == "object" && i) ? (a++, !0) : !1,
68
- _flushBatch: (e, n) => {
69
- c && (e ? (n || t.epoch++, d(1)) : d(0), c = !1, f.hasBatchValue = !1, l = i);
68
+ _flushBatch: () => {
69
+ if (l) {
70
+ if (!Object.is(u, i) || typeof i == "object" && i) {
71
+ a++, t.epoch++, t.log({
72
+ type: "signal",
73
+ label: o || "signal_batched",
74
+ details: {
75
+ from: u,
76
+ to: i
77
+ },
78
+ isInternalCoreSignal: s
79
+ });
80
+ for (let e of c) {
81
+ let n = e._node || e;
82
+ if (n.type === "effect") n.isDirty = !0, t.scheduleEffect(e);
83
+ else if (n.markDirty) n.markDirty(2);
84
+ else if (typeof e == "function") try {
85
+ e(i);
86
+ } catch (e) {
87
+ console.error(e);
88
+ }
89
+ }
90
+ }
91
+ l = !1, u = i;
92
+ }
93
+ },
94
+ get hasBatchValue() {
95
+ return l;
96
+ },
97
+ destroy: () => {
98
+ c && c.clear(), t.batchedSignals && t.batchedSignals.delete(p), l = !1, i = void 0, u = void 0;
70
99
  }
71
100
  };
72
- return f._node = u, f.subscribers = s, f;
101
+ return p._node = d, p.subscribers = c, p;
73
102
  }
74
103
  //#endregion
75
104
  export { t as createSignal };
@@ -1 +1 @@
1
- {"version":3,"file":"core.method.signal.mjs","names":[],"sources":["../src/core/core.method.signal.ts"],"sourcesContent":["import { getExtractedValues } from '../utils/getExtractedValues'\nimport { Signal, SignalOptions } from './types'\n\nexport function createSignal<T>(\n engine: any,\n initialValue: T,\n optionsOrName?: SignalOptions<T> | string\n): Signal<T> {\n let value = initialValue\n let version = 0\n let name = typeof optionsOrName === 'string' ? optionsOrName : optionsOrName?.name\n\n const extracted = !!name ? getExtractedValues({\n tested: [name],\n expectedKey: 'CORE_INTERNAL_SIGNAL',\n valueType: 'number',\n })?.[0] : null\n const isInternalCoreSignal = extracted && extracted === '1'\n\n const subscribers = new Set<any>()\n\n let hasBatchValue = false\n let batchInitialValue: T = initialValue\n\n const signalNode = {\n type: 'signal',\n get version() { return version },\n subscribers\n }\n\n const notifySubscribers = (parentState: number = 2) => {\n for (const sub of subscribers) {\n const rawSub = sub._node || sub\n if (rawSub.type === 'effect') {\n rawSub.isDirty = true\n engine.scheduleEffect(sub)\n } else if (rawSub.type === 'computed') {\n if (rawSub.markDirty) rawSub.markDirty(parentState)\n } else {\n if (typeof sub === 'function') {\n try { sub(value) } catch (err) { console.error(err) }\n } else if (sub && typeof sub.run === 'function') {\n try { sub.run() } catch (err) { console.error(err) }\n }\n }\n }\n }\n\n const signalInstance: Signal<T> = {\n get value() {\n const consumer = engine.activeConsumer\n if (consumer) {\n subscribers.add(engine.activeConsumer)\n engine.activeConsumer.dependencies.add(signalInstance)\n\n const consumerRaw = consumer._node || consumer\n if (consumerRaw.depth !== undefined && consumerRaw.depth === 1) {\n consumerRaw.depth = 2\n }\n\n if (consumer.activeRunId !== undefined) {\n (signalInstance as any)._lastSeenInRunId = consumer.activeRunId\n }\n }\n return value\n },\n\n set value(newValue: T) {\n const isObjectKick = value === newValue && value !== null && typeof value === 'object'\n if (Object.is(value, newValue) && !isObjectKick) return\n\n if (optionsOrName && typeof optionsOrName === 'object' && optionsOrName.validate) {\n const validation = optionsOrName.validate(newValue)\n if (validation !== true) {\n console.error(typeof validation === 'string' ? validation : '[Validation Error]')\n return\n }\n }\n\n if (engine.batchDepth > 0) {\n if (!hasBatchValue) {\n hasBatchValue = true\n batchInitialValue = value\n }\n value = newValue\n\n ;(signalInstance as any).hasBatchValue = true\n notifySubscribers(1) // Мягкая маркировка CHECK (1) интра-ран чтений батча\n\n engine.batchedSignals.add(signalInstance)\n return\n }\n\n const oldValue = value\n value = newValue\n\n version++\n engine.epoch++\n\n notifySubscribers(2)\n if (engine.batchDepth === 0) engine.flushEffects()\n },\n\n get version() { return version },\n type: 'signal',\n\n subscribe(cb: (val: T) => void) {\n subscribers.add(cb)\n cb(value)\n return () => { subscribers.delete(cb) }\n },\n\n // ⚛️ ФАЗА 1: Чистая фиксация новых версий\n _applyBatchValue: () => {\n if (!hasBatchValue) return false\n const wasChanged = !Object.is(batchInitialValue, value) || (value !== null && typeof value === 'object')\n if (wasChanged) {\n version++\n return true\n }\n return false\n },\n\n // ⚛️ ФАЗА 2: Чистый атомарный push-уведомитель\n _flushBatch: (wasChanged: boolean, isAlreadyEpochShifted?: boolean) => {\n if (!hasBatchValue) return\n\n if (wasChanged) {\n if (!isAlreadyEpochShifted) {\n engine.epoch++\n }\n // ⚛️ КAНОНИЧЕСКИЙ БАТЧИНГ: Переводим в CHECK (1) вместо DIRTY (2).\n // Это блокирует веерные перезапуски сирот и алмазов на выходе из батча!\n notifySubscribers(1)\n } else {\n notifySubscribers(0)\n }\n\n hasBatchValue = false\n ;(signalInstance as any).hasBatchValue = false\n batchInitialValue = value\n }\n\n } as any\n\n ;(signalInstance as any)._node = signalNode\n ;(signalInstance as any).subscribers = subscribers\n return signalInstance\n}\n"],"mappings":";;AAGA,SAAgB,EACd,GACA,GACA,GACW;CACX,IAAI,IAAQ,GACR,IAAU,GACV,IAAO,OAAO,KAAkB,WAAW,IAAgB,GAAe;CAE5D,KAAS,EAAmB;EAC5C,QAAQ,CAAC,CAAI;EACb,aAAa;EACb,WAAW;CACb,CAAC,CAAC,GAAG;CAGL,IAAM,oBAAc,IAAI,IAAS,GAE7B,IAAgB,IAChB,IAAuB,GAErB,IAAa;EACjB,MAAM;EACN,IAAI,UAAU;GAAE,OAAO;EAAQ;EAC/B;CACF,GAEM,KAAqB,IAAsB,MAAM;EACrD,KAAK,IAAM,KAAO,GAAa;GAC7B,IAAM,IAAS,EAAI,SAAS;GAC5B,IAAI,EAAO,SAAS,UAElB,AADA,EAAO,UAAU,IACjB,EAAO,eAAe,CAAG;QACpB,IAAI,EAAO,SAAS,YACrB,EAAO,aAAW,EAAO,UAAU,CAAW;QAElD,IAAI,OAAO,KAAQ,YACjB,IAAI;IAAE,EAAI,CAAK;GAAE,SAAS,GAAK;IAAE,QAAQ,MAAM,CAAG;GAAE;QAC/C,IAAI,KAAO,OAAO,EAAI,OAAQ,YACnC,IAAI;IAAE,EAAI,IAAI;GAAE,SAAS,GAAK;IAAE,QAAQ,MAAM,CAAG;GAAE;EAGzD;CACF,GAEM,IAA4B;EAChC,IAAI,QAAQ;GACV,IAAM,IAAW,EAAO;GACxB,IAAI,GAAU;IAEZ,AADA,EAAY,IAAI,EAAO,cAAc,GACrC,EAAO,eAAe,aAAa,IAAI,CAAc;IAErD,IAAM,IAAc,EAAS,SAAS;IAKtC,AAJI,EAAY,UAAU,KAAA,KAAa,EAAY,UAAU,MAC3D,EAAY,QAAQ,IAGlB,EAAS,gBAAgB,KAAA,MAC3B,EAAwB,mBAAmB,EAAS;GAExD;GACA,OAAO;EACT;EAEA,IAAI,MAAM,GAAa;GAEjB,aAAO,GAAG,GAAO,CAAQ,KAAK,EADb,MAAU,KAA8B,OAAO,KAAU,YAAnC,KAG3C;QAAI,KAAiB,OAAO,KAAkB,YAAY,EAAc,UAAU;KAChF,IAAM,IAAa,EAAc,SAAS,CAAQ;KAClD,IAAI,MAAe,IAAM;MACvB,QAAQ,MAAM,OAAO,KAAe,WAAW,IAAa,oBAAoB;MAChF;KACF;IACF;IAEA,IAAI,EAAO,aAAa,GAAG;KAUzB,AATK,MACH,IAAgB,IAChB,IAAoB,IAEtB,IAAQ,GAEP,EAAwB,gBAAgB,IACzC,EAAkB,CAAC,GAEnB,EAAO,eAAe,IAAI,CAAc;KACxC;IACF;IASA,AANA,IAAQ,GAER,KACA,EAAO,SAEP,EAAkB,CAAC,GACf,EAAO,eAAe,KAAG,EAAO,aAAa;GAvBjD;EAwBF;EAEA,IAAI,UAAU;GAAE,OAAO;EAAQ;EAC/B,MAAM;EAEN,UAAU,GAAsB;GAG9B,OAFA,EAAY,IAAI,CAAE,GAClB,EAAG,CAAK,SACK;IAAE,EAAY,OAAO,CAAE;GAAE;EACxC;EAGA,wBACO,MACc,CAAC,OAAO,GAAG,GAAmB,CAAK,KAAwB,OAAO,KAAU,YAAnC,MAE1D,KACO,MAEF;EAIT,cAAc,GAAqB,MAAoC;GAChE,MAED,KACG,KACH,EAAO,SAIT,EAAkB,CAAC,KAEnB,EAAkB,CAAC,GAGrB,IAAgB,IACf,EAAwB,gBAAgB,IACzC,IAAoB;EACtB;CAEF;CAIA,OAFC,EAAwB,QAAQ,GAChC,EAAwB,cAAc,GAChC;AACT"}
1
+ {"version":3,"file":"core.method.signal.mjs","names":[],"sources":["../src/core/core.method.signal.ts"],"sourcesContent":["import { getExtractedValues } from '../utils/getExtractedValues'\nimport { Signal, SignalOptions } from './types'\n\nexport function createSignal<T>(\n engine: any,\n initialValue: T,\n optionsOrName?: SignalOptions<T> | string\n): Signal<T> {\n let value = initialValue\n let version = 0\n let name = typeof optionsOrName === 'string' ? optionsOrName : optionsOrName?.name\n const isInternalCoreSignal = !!name && getExtractedValues({\n tested: [name],\n expectedKey: 'CORE_INTERNAL_SIGNAL',\n valueType: 'number',\n })?.[0] === '1' || false\n const subscribers = new Set<any>()\n\n let hasBatchValue = false\n let batchInitialValue: T = initialValue\n\n const signalNode = {\n type: 'signal',\n get version() { return version },\n subscribers\n }\n\n const notifySubscribers = () => {\n for (const sub of subscribers) {\n const rawSub = sub._node || sub\n if (rawSub.type === 'effect') {\n rawSub.isDirty = true\n engine.scheduleEffect(sub)\n } else if (rawSub.type === 'computed') {\n if (rawSub.markDirty) rawSub.markDirty(2)\n } else {\n if (typeof sub === 'function') {\n try { sub(value) } catch (err) { console.error(err) }\n } else if (sub && typeof sub.run === 'function') {\n try { sub.run() } catch (err) { console.error(err) }\n }\n }\n }\n }\n\n const signalInstance: Signal<T> = {\n get value() {\n const consumer = engine.activeConsumer\n if (consumer) {\n subscribers.add(engine.activeConsumer)\n engine.activeConsumer.dependencies.add(signalInstance)\n\n if (consumer.activeRunId !== undefined) {\n (signalInstance as any)._lastSeenInRunId = consumer.activeRunId\n }\n }\n return value\n },\n\n set value(newValue: T) {\n const isObjectKick = value === newValue && value !== null && typeof value === 'object'\n if (Object.is(value, newValue) && !isObjectKick) return\n\n if (optionsOrName && typeof optionsOrName === 'object' && optionsOrName.validate) {\n const validation = optionsOrName.validate(newValue)\n if (validation !== true) {\n console.error(typeof validation === 'string' ? validation : '[Validation Error]')\n return\n }\n }\n\n if (engine.batchDepth > 0) {\n if (!hasBatchValue) {\n hasBatchValue = true\n batchInitialValue = value\n }\n value = newValue\n engine.batchedSignals.add(signalInstance)\n return\n }\n\n const oldValue = value\n value = newValue\n\n version++\n engine.epoch++\n\n engine.log({\n type: 'signal',\n label: name || 'signal',\n details: { from: oldValue, to: newValue },\n isInternalCoreSignal\n })\n\n notifySubscribers()\n if (engine.batchDepth === 0) engine.flushEffects()\n },\n\n get version() { return version },\n type: 'signal',\n\n subscribe(cb: (val: T) => void) {\n subscribers.add(cb)\n cb(value)\n return () => { subscribers.delete(cb) }\n },\n\n _flushBatch: () => {\n if (!hasBatchValue) return\n\n const wasChanged = !Object.is(batchInitialValue, value) || (value !== null && typeof value === 'object')\n\n if (wasChanged) {\n version++\n engine.epoch++\n\n engine.log({\n type: 'signal',\n label: name || 'signal_batched',\n details: { from: batchInitialValue, to: value },\n isInternalCoreSignal\n })\n\n for (const sub of subscribers) {\n const rawSub = sub._node || sub\n if (rawSub.type === 'effect') {\n rawSub.isDirty = true\n engine.scheduleEffect(sub)\n } else if (rawSub.markDirty) {\n rawSub.markDirty(2)\n } else if (typeof sub === 'function') {\n try { sub(value) } catch (err) { console.error(err) }\n }\n }\n }\n\n hasBatchValue = false\n batchInitialValue = value\n },\n\n get hasBatchValue() { return hasBatchValue },\n\n // ⚛️ ФИКС ДЛЯ РЕЛИЗА 2.5.0: Метод тотальной деструкции сигнала\n destroy: () => {\n if (subscribers) {\n subscribers.clear()\n }\n if (engine.batchedSignals) {\n engine.batchedSignals.delete(signalInstance)\n }\n hasBatchValue = false\n // Помогаем GC, убирая ссылки на тяжелые объекты\n value = undefined as any\n batchInitialValue = undefined as any\n }\n } as any\n\n ;(signalInstance as any)._node = signalNode\n ;(signalInstance as any).subscribers = subscribers\n return signalInstance\n}\n"],"mappings":"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"}
package/dist/core.mjs CHANGED
@@ -3,8 +3,57 @@ import { createSignal as t } from "./core.method.signal.mjs";
3
3
  import { executeUntrack as n } from "./core.method.untrack.mjs";
4
4
  import { createReactive as r } from "./core.method.reactive.mjs";
5
5
  import { createEffect as i } from "./core.method.effect.mjs";
6
+ import { ReactiveDebounceLogger as a } from "./core.logger.mjs";
7
+ import { createResource as o } from "./core.method.resource.mjs";
6
8
  //#region src/core/core.ts
7
- var a = class {
9
+ var s = {
10
+ signal: "background: #007acc; color: #fff; padding: 2px 6px; border-radius: 4px; font-weight: bold;",
11
+ computed: "background: #42b883; color: #fff; padding: 2px 6px; border-radius: 4px; font-weight: bold;",
12
+ effect: "background: #e01e5a; color: #fff; padding: 2px 6px; border-radius: 4px; font-weight: bold;",
13
+ batch: "background: #7952b3; color: #fff; padding: 2px 6px; border-radius: 4px; font-weight: bold;",
14
+ resource: "background: #d97706; color: #fff; padding: 2px 6px; border-radius: 4px; font-weight: bold;",
15
+ reactive: "background: #007acc; color: #fff; padding: 2px 6px; border-radius: 4px; font-weight: bold;"
16
+ }, c = null;
17
+ function l(e) {
18
+ if (e === null) return "null";
19
+ if (e === void 0) return "undefined";
20
+ if (typeof e == "object") try {
21
+ return JSON.stringify(e);
22
+ } catch {
23
+ return "[Cyclic Object or Layer]";
24
+ }
25
+ return String(e);
26
+ }
27
+ function u(e, t, n) {
28
+ c || (c = {
29
+ id: Math.random().toString(36).substring(2, 9),
30
+ pendingLogQueue: [],
31
+ isFlushing: !1
32
+ }, queueMicrotask(() => d())), c.pendingLogQueue.push({
33
+ type: e,
34
+ label: t,
35
+ from: n?.from,
36
+ to: n?.to,
37
+ payload: n?.payload,
38
+ timestamp: Date.now()
39
+ });
40
+ }
41
+ function d() {
42
+ if (!c || c.isFlushing) return;
43
+ c.isFlushing = !0;
44
+ let e = c.pendingLogQueue;
45
+ if (e.length === 0) {
46
+ c = null;
47
+ return;
48
+ }
49
+ console.groupCollapsed(`%cREACTIVE TRANSACTION%c [id: ${c.id}] (${e.length} operations)`, "background: #7952b3; color: #fff; padding: 2px 6px; border-radius: 4px; font-weight: bold;", "color: #888; font-weight: normal;");
50
+ for (let t of e) {
51
+ let e = s[t.type], n = t.from !== void 0 || t.to !== void 0, r = `%c${t.type.toUpperCase()}%c ${t.label}`;
52
+ n && (t.from ? r += ` ${l(t.from)} → ${l(t.to)}` : r += ` (${l(t.to)})`), t.payload === void 0 ? console.log(r, e, "color: inherit;") : (console.groupCollapsed(r, e, "color: inherit;"), console.log("Payload:", t.payload), console.groupEnd());
53
+ }
54
+ console.groupEnd(), c = null;
55
+ }
56
+ var f = class {
8
57
  frameworkPrefix = "core";
9
58
  logger;
10
59
  epoch = 0;
@@ -14,7 +63,6 @@ var a = class {
14
63
  pendingEffects = [];
15
64
  maxPendingDepth = 0;
16
65
  computedCache = /* @__PURE__ */ new WeakMap();
17
- computedStringCache = /* @__PURE__ */ new Map();
18
66
  diRegistry = /* @__PURE__ */ new Map();
19
67
  diCache = /* @__PURE__ */ new Map();
20
68
  proxyCache = /* @__PURE__ */ new WeakMap();
@@ -24,37 +72,30 @@ var a = class {
24
72
  batchedSignals = /* @__PURE__ */ new Set();
25
73
  activeOwner = null;
26
74
  pendingCleanups = /* @__PURE__ */ new Set();
27
- isLoggingEnabled = !1;
28
- _poolArr = [];
29
75
  queueCleanup(e) {
30
76
  this.pendingCleanups.add(e);
31
77
  }
32
78
  constructor(e) {
33
- this.logger = e?.logger || { isEnabled: !1 }, this.isLoggingEnabled = !!this.logger.isEnabled;
79
+ this.logger = e?.logger || { isEnabled: !1 };
34
80
  }
35
81
  scheduleEffect(e) {
36
- if (e._isScheduled) return;
37
- e._isScheduled = !0;
38
82
  let t = e.depth || 0;
39
83
  this.pendingEffects[t] || (this.pendingEffects[t] = /* @__PURE__ */ new Set()), this.pendingEffects[t].add(e), t > this.maxPendingDepth && (this.maxPendingDepth = t);
40
84
  }
85
+ queueLog(e, t, n) {
86
+ u(e, t, n);
87
+ }
41
88
  batch(e) {
42
89
  this.batchDepth++;
43
90
  try {
44
91
  return e();
45
92
  } finally {
46
93
  if (this.batchDepth--, this.batchDepth === 0) {
47
- if (this.batchIterationId ||= 0, this.batchIterationId++, this.batchedSignals.size > 0) {
48
- let e = /* @__PURE__ */ new Map();
49
- for (let t of this.batchedSignals) t._applyBatchValue && e.set(t, t._applyBatchValue());
50
- this.epoch++;
51
- for (let t of this.batchedSignals) if (t._flushBatch) {
52
- let n = e.get(t) ?? !1;
53
- t._flushBatch(n, !0);
54
- }
94
+ if (this.batchedSignals.size > 0) {
95
+ for (let e of this.batchedSignals) e._flushBatch && e._flushBatch();
55
96
  this.batchedSignals.clear();
56
97
  }
57
- this.flushEffects();
98
+ this.flushEffects(), this.batchComputedCache &&= (this.batchComputedCache.clear(), null);
58
99
  }
59
100
  }
60
101
  }
@@ -67,7 +108,7 @@ var a = class {
67
108
  if (!t || t.size === 0) continue;
68
109
  let n = Array.from(t);
69
110
  t.clear();
70
- for (let e of n) if (!e.isDisposed && (e._isScheduled = !1, e.isDirty)) {
111
+ for (let e of n) if (!e.isDisposed && e.isDirty) {
71
112
  if (e.dependencies && e.dependencies.size > 0) {
72
113
  let t = !1;
73
114
  for (let n of e.dependencies) {
@@ -99,6 +140,9 @@ var a = class {
99
140
  this.activeConsumer = e;
100
141
  }
101
142
  }
143
+ log(e) {
144
+ !this.logger || !this.logger.isEnabled || a.processLog(this.logger, u, e);
145
+ }
102
146
  signal(e, n) {
103
147
  return t(this, e, n);
104
148
  }
@@ -126,6 +170,10 @@ var a = class {
126
170
  if (this.diRegistry.has(e)) {
127
171
  let t = this.diRegistry.get(e);
128
172
  if (typeof t == "function") {
173
+ if (t._isMockFunction) {
174
+ let n = t(this);
175
+ return n === void 0 ? t : (this.diCache.set(e, n), n);
176
+ }
129
177
  let n = t.toString();
130
178
  if (!(n.startsWith("class ") || n.startsWith("class{") || t.prototype && t.prototype.constructor === t && !n.startsWith("function") && !n.includes("=>"))) {
131
179
  let n = t(this);
@@ -144,97 +192,22 @@ var a = class {
144
192
  this.cycleDetectionStack.delete(e);
145
193
  }
146
194
  }
195
+ delay(e, t) {
196
+ return new Promise((n, r) => {
197
+ if (t.aborted) return r(new DOMException("Aborted", "AbortError"));
198
+ let i = setTimeout(() => {
199
+ t.removeEventListener("abort", a), n();
200
+ }, e), a = () => {
201
+ clearTimeout(i), r(new DOMException("Aborted", "AbortError"));
202
+ };
203
+ t.addEventListener("abort", a, { once: !0 });
204
+ });
205
+ }
147
206
  resource(e, t, n) {
148
- let r = n && typeof n == "object", i = r ? n.name || "unnamed_resource" : n || "unnamed_resource", a = r ? n : {}, o = a.resetDataOnSourceChange ?? !0, s = a.responseValidate, c = a.validateBeforeFetch, l = this.signal({
149
- data: null,
150
- loading: !0,
151
- error: null,
152
- isRetrying: !1
153
- }, `[CORE_INTERNAL_SIGNAL=1]:resource:state:${i}`), u = async (t, n, r = !1) => {
154
- if (!n.aborted) {
155
- if (c) {
156
- let e = c(t);
157
- if (e === !1 || typeof e == "string") {
158
- if (n.aborted) return;
159
- let t = typeof e == "string" ? e : "Pre-fetch validation failed";
160
- l.value = {
161
- data: r ? null : l.value.data,
162
- loading: !1,
163
- error: t,
164
- isRetrying: !1
165
- };
166
- return;
167
- }
168
- }
169
- l.value = {
170
- data: r && o ? null : l.value.data,
171
- loading: !0,
172
- error: null,
173
- isRetrying: !1
174
- };
175
- try {
176
- let r = await e(t, n);
177
- if (n.aborted) return;
178
- if (s) {
179
- let e = s(r);
180
- if (e === !1 || typeof e == "string") {
181
- l.value = {
182
- data: null,
183
- loading: !1,
184
- error: typeof e == "string" ? e : "Validation failed",
185
- isRetrying: !1
186
- };
187
- return;
188
- }
189
- }
190
- l.value = {
191
- data: r,
192
- loading: !1,
193
- error: null,
194
- isRetrying: !1
195
- };
196
- } catch (e) {
197
- if (n.aborted) return;
198
- l.value = {
199
- data: null,
200
- loading: !1,
201
- error: e.message || "Fetch error",
202
- isRetrying: !1
203
- };
204
- }
205
- }
206
- }, d = null;
207
- return this.effect(() => {
208
- let e = t ? t.value : void 0, n = new AbortController();
209
- return d = n, this.untrack(() => {
210
- u(e, n.signal, !0);
211
- }), () => n.abort();
212
- }), {
213
- get data() {
214
- return l.value.data;
215
- },
216
- get loading() {
217
- return l.value.loading;
218
- },
219
- get error() {
220
- return l.value.error;
221
- },
222
- get isRetrying() {
223
- return l.value.isRetrying;
224
- },
225
- get value() {
226
- return l.value;
227
- },
228
- refetch: () => {
229
- d?.abort();
230
- let e = new AbortController();
231
- d = e, u(t ? t.value : void 0, e.signal, !1);
232
- },
233
- subscribe: (e) => l.subscribe(e)
234
- };
235
- }
236
- }, o = class extends a {};
207
+ return o(this, e, t, n);
208
+ }
209
+ };
237
210
  //#endregion
238
- export { o as ReactiveEngineAutomatic, a as ReactiveEngineCore };
211
+ export { f as ReactiveEngine, f as ReactiveEngineAutomatic, f as ReactiveEngineCore, d as flushLogs, u as queueLog };
239
212
 
240
213
  //# sourceMappingURL=core.mjs.map