@raphy-js/raph 1.0.0-dev.2
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/LICENSE +202 -0
- package/ReadMe.md +153 -0
- package/dist/api/Raph.d.ts +228 -0
- package/dist/api/errors.d.ts +20 -0
- package/dist/api/public.d.ts +22 -0
- package/dist/api/types.d.ts +25 -0
- package/dist/debug/api/Raph.cjs +1 -0
- package/dist/debug/api/Raph.js +419 -0
- package/dist/debug/api/errors.cjs +1 -0
- package/dist/debug/api/errors.js +14 -0
- package/dist/debug/api/public.cjs +1 -0
- package/dist/debug/api/public.js +40 -0
- package/dist/debug/api/types.cjs +1 -0
- package/dist/debug/api/types.js +1 -0
- package/dist/debug/path/AdapterPathStore.cjs +1 -0
- package/dist/debug/path/AdapterPathStore.js +133 -0
- package/dist/debug/path/DerivedRegistry.cjs +1 -0
- package/dist/debug/path/DerivedRegistry.js +157 -0
- package/dist/debug/path/MetaController.cjs +1 -0
- package/dist/debug/path/MetaController.js +214 -0
- package/dist/debug/path/PathEventHub.cjs +1 -0
- package/dist/debug/path/PathEventHub.js +148 -0
- package/dist/debug/path/PathStore.cjs +1 -0
- package/dist/debug/path/PathStore.js +326 -0
- package/dist/debug/path/RaphDerivedHandle.cjs +1 -0
- package/dist/debug/path/RaphDerivedHandle.js +125 -0
- package/dist/debug/path/RaphKernel.cjs +1 -0
- package/dist/debug/path/RaphKernel.js +636 -0
- package/dist/debug/path/RaphMeta.cjs +1 -0
- package/dist/debug/path/RaphMeta.js +68 -0
- package/dist/debug/path/RaphMetaStore.cjs +1 -0
- package/dist/debug/path/RaphMetaStore.js +184 -0
- package/dist/debug/path/data-adapter.cjs +1 -0
- package/dist/debug/path/data-adapter.js +356 -0
- package/dist/debug/path/data-draft.cjs +1 -0
- package/dist/debug/path/data-draft.js +71 -0
- package/dist/debug/path/data-path.cjs +1 -0
- package/dist/debug/path/data-path.js +423 -0
- package/dist/debug/path/derived-collection.cjs +1 -0
- package/dist/debug/path/derived-collection.js +179 -0
- package/dist/debug/path/derived-strategies.cjs +1 -0
- package/dist/debug/path/derived-strategies.js +20 -0
- package/dist/debug/path/meta.types.cjs +1 -0
- package/dist/debug/path/meta.types.js +1 -0
- package/dist/debug/path/path-router.cjs +1 -0
- package/dist/debug/path/path-router.js +86 -0
- package/dist/debug/path/path.types.cjs +1 -0
- package/dist/debug/path/path.types.js +1 -0
- package/dist/debug/path/public.cjs +1 -0
- package/dist/debug/path/public.js +18 -0
- package/dist/debug/path/segment-key.cjs +1 -0
- package/dist/debug/path/segment-key.js +12 -0
- package/dist/debug/reactivity/engine.cjs +1 -0
- package/dist/debug/reactivity/engine.js +1133 -0
- package/dist/debug/reactivity/scope.cjs +1 -0
- package/dist/debug/reactivity/scope.js +274 -0
- package/dist/debug/reactivity/types.cjs +1 -0
- package/dist/debug/reactivity/types.js +1 -0
- package/dist/debug/reactivity/watch.cjs +1 -0
- package/dist/debug/reactivity/watch.js +64 -0
- package/dist/debug/runtime/PathHandle.cjs +1 -0
- package/dist/debug/runtime/PathHandle.js +139 -0
- package/dist/debug/runtime/RaphDebug.cjs +1 -0
- package/dist/debug/runtime/RaphDebug.js +15 -0
- package/dist/debug/runtime/RaphFrameLoop.cjs +1 -0
- package/dist/debug/runtime/RaphFrameLoop.js +106 -0
- package/dist/debug/runtime/RaphNode.cjs +1 -0
- package/dist/debug/runtime/RaphNode.js +143 -0
- package/dist/debug/runtime/RaphPhasePipeline.cjs +1 -0
- package/dist/debug/runtime/RaphPhasePipeline.js +526 -0
- package/dist/debug/runtime/RaphRuntime.cjs +1 -0
- package/dist/debug/runtime/RaphRuntime.js +700 -0
- package/dist/debug/runtime/RaphScope.cjs +1 -0
- package/dist/debug/runtime/RaphScope.js +64 -0
- package/dist/debug/runtime/RuntimeReactivity.cjs +1 -0
- package/dist/debug/runtime/RuntimeReactivity.js +154 -0
- package/dist/debug/runtime/RuntimeWatch.cjs +1 -0
- package/dist/debug/runtime/RuntimeWatch.js +71 -0
- package/dist/debug/runtime/disposal.cjs +1 -0
- package/dist/debug/runtime/disposal.js +9 -0
- package/dist/debug/runtime/errors.cjs +1 -0
- package/dist/debug/runtime/errors.js +12 -0
- package/dist/debug/runtime/parent-graph.cjs +1 -0
- package/dist/debug/runtime/parent-graph.js +10 -0
- package/dist/debug/runtime/phase.types.cjs +1 -0
- package/dist/debug/runtime/phase.types.js +8 -0
- package/dist/debug/runtime/public.cjs +1 -0
- package/dist/debug/runtime/public.js +18 -0
- package/dist/debug/runtime/runtime-reactivity.types.cjs +1 -0
- package/dist/debug/runtime/runtime-reactivity.types.js +1 -0
- package/dist/index.cjs +1 -0
- package/dist/index.js +40 -0
- package/dist/path/AdapterPathStore.d.ts +45 -0
- package/dist/path/DerivedRegistry.d.ts +67 -0
- package/dist/path/MetaController.d.ts +85 -0
- package/dist/path/PathEventHub.d.ts +48 -0
- package/dist/path/PathStore.d.ts +51 -0
- package/dist/path/RaphDerivedHandle.d.ts +97 -0
- package/dist/path/RaphKernel.d.ts +166 -0
- package/dist/path/RaphMeta.d.ts +45 -0
- package/dist/path/RaphMetaStore.d.ts +45 -0
- package/dist/path/data-adapter.d.ts +78 -0
- package/dist/path/data-draft.d.ts +4 -0
- package/dist/path/data-path.d.ts +97 -0
- package/dist/path/derived-collection.d.ts +30 -0
- package/dist/path/derived-strategies.d.ts +15 -0
- package/dist/path/meta.types.d.ts +33 -0
- package/dist/path/path-router.d.ts +21 -0
- package/dist/path/path.types.d.ts +26 -0
- package/dist/path/public.d.ts +14 -0
- package/dist/path/segment-key.d.ts +2 -0
- package/dist/path.cjs +1 -0
- package/dist/path.js +18 -0
- package/dist/raph.cjs +1 -0
- package/dist/raph.js +40 -0
- package/dist/reactivity/engine.d.ts +379 -0
- package/dist/reactivity/scope.d.ts +146 -0
- package/dist/reactivity/types.d.ts +150 -0
- package/dist/reactivity/watch.d.ts +15 -0
- package/dist/reactivity.cjs +1 -0
- package/dist/reactivity.js +14 -0
- package/dist/runtime/PathHandle.d.ts +72 -0
- package/dist/runtime/RaphDebug.d.ts +32 -0
- package/dist/runtime/RaphFrameLoop.d.ts +51 -0
- package/dist/runtime/RaphNode.d.ts +68 -0
- package/dist/runtime/RaphPhasePipeline.d.ts +133 -0
- package/dist/runtime/RaphRuntime.d.ts +285 -0
- package/dist/runtime/RaphScope.d.ts +50 -0
- package/dist/runtime/RuntimeReactivity.d.ts +40 -0
- package/dist/runtime/RuntimeWatch.d.ts +28 -0
- package/dist/runtime/disposal.d.ts +1 -0
- package/dist/runtime/errors.d.ts +16 -0
- package/dist/runtime/parent-graph.d.ts +5 -0
- package/dist/runtime/phase.types.d.ts +49 -0
- package/dist/runtime/public.d.ts +13 -0
- package/dist/runtime/runtime-reactivity.types.d.ts +9 -0
- package/dist/runtime.cjs +1 -0
- package/dist/runtime.js +18 -0
- package/package.json +109 -0
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
var d = Object.defineProperty;
|
|
2
|
+
var f = (s, r, t) => r in s ? d(s, r, { enumerable: !0, configurable: !0, writable: !0, value: t }) : s[r] = t;
|
|
3
|
+
var h = (s, r, t) => f(s, typeof r != "symbol" ? r + "" : r, t);
|
|
4
|
+
import { throwDisposalErrors as m } from "./disposal.js";
|
|
5
|
+
import { RaphCrossRuntimeError as p } from "./errors.js";
|
|
6
|
+
import { RaphScope as _ } from "./RaphScope.js";
|
|
7
|
+
let y = 0;
|
|
8
|
+
class a extends _ {
|
|
9
|
+
/**
|
|
10
|
+
* Создаёт node внутри ownership tree указанного runtime.
|
|
11
|
+
*/
|
|
12
|
+
constructor(t, i = {}, n) {
|
|
13
|
+
const o = n ?? (t instanceof a ? t.runtime : t ?? void 0);
|
|
14
|
+
if (o === void 0)
|
|
15
|
+
throw new Error("[RaphNode] A root node requires an explicit runtime.");
|
|
16
|
+
const e = t instanceof a ? t : (t == null ? void 0 : t.root) ?? null;
|
|
17
|
+
super(i.id ?? `node-${y++}`, o);
|
|
18
|
+
// Описывают положение и порядок node в ownership tree.
|
|
19
|
+
h(this, "priority");
|
|
20
|
+
h(this, "_parent");
|
|
21
|
+
h(this, "_children", []);
|
|
22
|
+
// Публикуют прикладной API и диагностические атрибуты node.
|
|
23
|
+
h(this, "api");
|
|
24
|
+
h(this, "meta");
|
|
25
|
+
h(this, "type");
|
|
26
|
+
if (e !== null && e.runtime !== o)
|
|
27
|
+
throw super.dispose(), new p("[Raph] Parent belongs to another runtime.");
|
|
28
|
+
try {
|
|
29
|
+
e == null || e._assertAlive();
|
|
30
|
+
} catch (u) {
|
|
31
|
+
throw super.dispose(), u;
|
|
32
|
+
}
|
|
33
|
+
const l = i.priority ?? 0;
|
|
34
|
+
c(l), this.priority = l, this._parent = e, this.meta = { ...i.meta }, this.type = i.type ?? "default", this.api = Object.freeze({}), e == null || e._children.push(this);
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Возвращает текущего родителя node либо null для root.
|
|
38
|
+
*/
|
|
39
|
+
get parent() {
|
|
40
|
+
return this._parent;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Возвращает снимок непосредственных дочерних nodes.
|
|
44
|
+
*/
|
|
45
|
+
get children() {
|
|
46
|
+
return this._children;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Перемещает node внутри ownership tree одного Runtime.
|
|
50
|
+
*/
|
|
51
|
+
addChild(t) {
|
|
52
|
+
if (this._assertAlive(), t._assertAlive(), t.runtime !== this.runtime)
|
|
53
|
+
throw new p("[Raph] Child belongs to another runtime.");
|
|
54
|
+
if (this === t)
|
|
55
|
+
throw new Error("[Raph] A node cannot become its own ancestor.");
|
|
56
|
+
for (let i = this._parent; i !== null; i = i.parent)
|
|
57
|
+
if (i === t)
|
|
58
|
+
throw new Error("[Raph] A node cannot become its own ancestor.");
|
|
59
|
+
if (t.parent === this)
|
|
60
|
+
return !0;
|
|
61
|
+
if (t._parent !== null) {
|
|
62
|
+
const i = t._parent._children, n = i.indexOf(t);
|
|
63
|
+
n >= 0 && i.splice(n, 1);
|
|
64
|
+
}
|
|
65
|
+
return t._parent = this, this._children.push(t), !0;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Обновляет изменяемые priority, meta и type node.
|
|
69
|
+
*/
|
|
70
|
+
options(t) {
|
|
71
|
+
this._assertAlive(), t.meta !== void 0 && (this.meta = { ...t.meta }), t.priority !== void 0 && (c(t.priority), this.priority = t.priority), t.type !== void 0 && (this.type = t.type);
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Показывает, ожидает ли node выполнения.
|
|
75
|
+
*/
|
|
76
|
+
dirty(t) {
|
|
77
|
+
this._assertAlive(), this.runtime.invalidateNode(this, t);
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Отсоединяет node от ownership tree с заданной lifecycle-семантикой.
|
|
81
|
+
*/
|
|
82
|
+
remove() {
|
|
83
|
+
this.dispose();
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Освобождает node вместе с дочерними owners и registrations.
|
|
87
|
+
*/
|
|
88
|
+
dispose() {
|
|
89
|
+
if (this._disposed || this._disposing)
|
|
90
|
+
return;
|
|
91
|
+
this._disposing = !0;
|
|
92
|
+
const t = [];
|
|
93
|
+
for (const i of [...this._children])
|
|
94
|
+
try {
|
|
95
|
+
i.dispose();
|
|
96
|
+
} catch (n) {
|
|
97
|
+
t.push(n);
|
|
98
|
+
}
|
|
99
|
+
if (this._children.length = 0, this._parent !== null) {
|
|
100
|
+
const i = this._parent._children.indexOf(this);
|
|
101
|
+
i >= 0 && this._parent._children.splice(i, 1);
|
|
102
|
+
}
|
|
103
|
+
this._parent = null;
|
|
104
|
+
try {
|
|
105
|
+
super.dispose();
|
|
106
|
+
} catch (i) {
|
|
107
|
+
t.push(i);
|
|
108
|
+
}
|
|
109
|
+
m(t, `[Raph] Node "${this.id}" disposal failed.`);
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Регистрирует path observer в phase pipeline.
|
|
113
|
+
*/
|
|
114
|
+
observeData(t, i) {
|
|
115
|
+
return this._assertAlive(), this.runtime.observeData(this, t, i);
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Регистрирует tracked executor указанной phase.
|
|
119
|
+
*/
|
|
120
|
+
track(t, i = {}) {
|
|
121
|
+
return this._assertAlive(), this.runtime.track(this, t, i);
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Однократно устанавливает immutable API, принадлежащий node.
|
|
125
|
+
* @internal
|
|
126
|
+
*/
|
|
127
|
+
_setApi(t) {
|
|
128
|
+
const i = typeof t == "object" && t !== null ? Object.freeze(t) : t;
|
|
129
|
+
Object.defineProperty(this, "api", {
|
|
130
|
+
configurable: !1,
|
|
131
|
+
enumerable: !0,
|
|
132
|
+
value: i,
|
|
133
|
+
writable: !1
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
function c(s) {
|
|
138
|
+
if (!Number.isFinite(s))
|
|
139
|
+
throw new TypeError("[Raph] Node priority must be finite.");
|
|
140
|
+
}
|
|
141
|
+
export {
|
|
142
|
+
a as RaphNode
|
|
143
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var w=Object.defineProperty;var k=(d,e,s)=>e in d?w(d,e,{enumerable:!0,configurable:!0,writable:!0,value:s}):d[e]=s;var h=(d,e,s)=>k(d,typeof e!="symbol"?e+"":e,s);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const m=require("../path/data-path.cjs"),v=require("../path/path-router.cjs"),b=1e4,y=()=>{};class P{constructor(e,s,t,n,a=()=>!1){h(this,"_observerRouter");h(this,"_phaseRouter",new v.PathRouter);h(this,"_observers");h(this,"_stopKernel");h(this,"_phases",[]);h(this,"_phaseByName",new Map);h(this,"_pending",new Map);h(this,"_tasks",new Map);h(this,"_phaseBindings",new Map);h(this,"_taskSequence",0);h(this,"_scheduled",!1);h(this,"_scheduleToken",0);h(this,"_frameHandle");h(this,"_frameHandleKind");h(this,"_configurationLocked",!1);h(this,"_running",!1);h(this,"_disposed",!1);h(this,"_firstFrameAt");h(this,"_lastFrameAt");h(this,"_frameNumber",0);h(this,"_frame",Object.freeze({now:0,delta:0,elapsed:0,frame:0}));this._kernel=e,this._root=s,this._scheduler=t,this._runUntracked=n,this._deferSync=a}get frame(){return this._frame}get phases(){return this._phases.map(e=>e.phase)}definePhases(e){if(this._assertAlive(),this._configurationLocked||this._firstFrameAt!==void 0)throw new Error("[Raph] Cannot redefine phases after phase pipeline execution has started.");const s=new Map,t=new v.PathRouter,n=[];for(const a of e){const r=a.name.trim();if(!r)throw new Error("[Raph] Phase name must not be empty.");if(s.has(r))throw new Error(`[Raph] Duplicate phase name "${r}".`);if(!R(a.traversal))throw new Error(`[Raph] Unsupported phase traversal "${String(a.traversal)}".`);if(!A(a.mode))throw new Error(`[Raph] Unsupported phase mode "${String(a.mode)}".`);if(a.each!==void 0&&typeof a.each!="function")throw new TypeError(`[Raph] Phase "${r}" each executor must be a function.`);if(a.all!==void 0&&typeof a.all!="function")throw new TypeError(`[Raph] Phase "${r}" all executor must be a function.`);if(a.each!==void 0&&a.all!==void 0)throw new TypeError(`[Raph] Phase "${r}" cannot define both each and all executors.`);const i=Object.freeze({...a,name:r,mode:a.mode??"dirty",routes:Object.freeze([...a.routes??[]])}),o={phase:i};n.push(o),s.set(r,o);for(const l of i.routes)t.add(m.DataPath.from(l)._asMask(),o)}this._assertRetainedPhases(s),this._phases=n,this._phaseByName=s,this._phaseRouter=t}addPhase(e){this.definePhases([...this._phases.map(s=>s.phase),e])}clearPhases(){this.definePhases([])}requirePhase(e){if(this._assertAlive(),!this._phaseByName.has(e))throw new Error(`[Raph] Phase "${e}" is not defined.`)}lockConfiguration(){this._assertAlive(),this._configurationLocked=!0}retainPhase(e){this.requirePhase(e),this._phaseBindings.set(e,(this._phaseBindings.get(e)??0)+1);let s=!0;return()=>{if(!s)return;s=!1;const t=(this._phaseBindings.get(e)??1)-1;t===0?this._phaseBindings.delete(e):this._phaseBindings.set(e,t)}}phaseMode(e){this._assertAlive();const s=this._phaseByName.get(e);if(s===void 0)throw new Error(`[Raph] Phase "${e}" is not defined.`);return s.phase.mode??"dirty"}registerEffect(e){return this.requirePhase(e),y}bindEffect(e,s,t,n){const a=this.registerEffect(e),r={active:!0,pending:!1,persistent:!0,priority:s,sequence:0,run:t,node:n};return{schedule:()=>{if(!r.active||r.pending||this._disposed||n!=null&&n.disposed)return;r.pending=!0,r.sequence=this._taskSequence++;let i=this._tasks.get(e);i===void 0&&(i=[],this._tasks.set(e,i)),i.push(r),this._schedule()},dispose:()=>{if(!r.active)return;r.active=!1,r.pending=!1,a();const i=this._tasks.get(e);if(i!==void 0){const o=i.indexOf(r);o!==-1&&i.splice(o,1),i.length===0&&this._tasks.delete(e)}this._hasPending()||this._cancelScheduled()}}}queueEffect(e,s,t,n=!0){this.requirePhase(e);const a={active:!0,pending:!0,persistent:!1,priority:s,sequence:this._taskSequence++,run:t};let r=this._tasks.get(e);return r===void 0&&(r=[],this._tasks.set(e,r)),r.push(a),n&&this._schedule(),()=>{if(!a.active)return;a.active=!1;const i=this._tasks.get(e);if(i!==void 0){const o=i.indexOf(a);o>=0&&i.splice(o,1),i.length===0&&this._tasks.delete(e)}this._hasPending()||this._cancelScheduled()}}request(){this._assertAlive(),this._hasPending()&&this._schedule()}requestAlwaysPhases(){this._assertAlive();for(const e of this._phases){const s=e.phase;if(s.mode!=="always"||s.traversal!=="all"||s.all===void 0)continue;let t=this._pending.get(s.name);t===void 0&&(t=new Map,this._pending.set(s.name,t)),u(t,this._root,[])}this._pending.size!==0&&this._schedule()}observeData(e,s,t){const n=t.phase.trim();if(!this._phaseByName.has(n))throw new Error(`[Raph] Phase "${n}" is not defined.`);return this._addObserver(e,s,n,t)}track(e,s,t){return this._addObserver(e,s,void 0,t)}invalidate(e,s){this.requirePhase(s);let t=this._pending.get(s);t===void 0&&(t=new Map,this._pending.set(s,t)),u(t,e,[]),this._schedule()}flush(){var n;if(this._assertAlive(),this._cancelScheduled(),this._running||!this._hasPending())return;this._running=!0;const e=[],s=this._nextFrame();let t=0;try{for(;this._hasPending()&&!this._disposed;){if(++t>b){this._pending.clear();for(const i of this._tasks.values())for(const o of i)o.active=!1;throw this._tasks.clear(),new Error("[Raph] Phase flush exceeded 10000 passes.")}const a=this._pending;this._pending=new Map;const r=this._tasks;this._tasks=new Map;for(const i of this._phases){if(this._disposed)break;const o=i.phase.name,l=a.get(o);if(l!==void 0&&l.size!==0){const f=this._expandContexts(i.phase,l,s);if(i.phase.each!==void 0)for(const c of f){if(this._disposed)break;if(!c.node.disposed)try{this._runUntracked(()=>i.phase.each(c))}catch(p){e.push(p)}}else if(i.phase.all!==void 0&&!this._disposed)try{this._runUntracked(()=>i.phase.all(f))}catch(c){e.push(c)}}if(this._disposed)break;const _=r.get(o);if(!(_===void 0||_.length===0)){_.length>1&&_.sort((f,c)=>c.priority-f.priority||f.sequence-c.sequence);for(const f of _){if(this._disposed)break;if(!(!f.active||!f.pending||(n=f.node)!=null&&n.disposed)){f.pending=!1,f.persistent||(f.active=!1);try{f.run()}catch(c){e.push(c)}}}}}}}finally{this._running=!1}if(e.length===1)throw e[0];if(e.length>1)throw new AggregateError(e,"[Raph] Multiple phase executors failed.")}dispose(){var e;if(!this._disposed){this._disposed=!0,this._cancelScheduled(),this._pending.clear();for(const s of this._tasks.values())for(const t of s)t.active=!1;if(this._tasks.clear(),this._phaseBindings.clear(),(e=this._stopKernel)==null||e.call(this),this._stopKernel=void 0,this._observers!==void 0){for(const s of this._observers){s.active=!1;for(const t of s.removeRoutes)t()}this._observers.clear(),this._observers=void 0}this._observerRouter=void 0,this._phases=[],this._phaseByName.clear(),this._phaseRouter=new v.PathRouter}}_debugPending(){return this._scheduled||this._running||this._hasPending()}_addObserver(e,s,t,n){this._assertAlive();const a=Array.isArray(s)?s:[s];if(a.length===0)throw new TypeError("[Raph] Phase observer requires at least one mask.");const r=new Map;for(const c of a){const p=m.DataPath.from(c,n)._asMask();r.set(p.canonical,p)}const i=this._observerRouter??(this._observerRouter=new v.PathRouter),o={active:!0,node:e,...t===void 0?{}:{phase:t},removeRoutes:[]},l=[...r.values()].map(c=>i.add(c,o));o.removeRoutes=l;const _=this._observers??(this._observers=new Set);_.add(o),this._ensureKernelWatch();let f=!0;return()=>{var c;if(f){f=!1,o.active=!1;for(const p of o.removeRoutes)p();_.delete(o),_.size===0&&(this._observers=void 0,this._observerRouter=void 0,(c=this._stopKernel)==null||c.call(this),this._stopKernel=void 0)}}}_ensureKernelWatch(){this._stopKernel??(this._stopKernel=this._kernel.watch("*",({events:e})=>{this._receive(e)}))}_assertRetainedPhases(e){for(const s of this._phaseBindings.keys())if(!e.has(s))throw new Error(`[Raph] Cannot remove phase "${s}" while it is still bound.`);for(const s of this._observers??[]){const t=s.phase;if(s.active&&t!==void 0&&!e.has(t))throw new Error(`[Raph] Cannot remove phase "${t}" while it is still observed.`)}for(const s of this._pending.keys())if(!e.has(s))throw new Error(`[Raph] Cannot remove phase "${s}" while it has pending work.`);for(const s of this._tasks.keys())if(!e.has(s))throw new Error(`[Raph] Cannot remove phase "${s}" while it has queued effects.`)}_receive(e){if(this._disposed)return;const s=this._observerRouter;if(s!==void 0){for(const t of e){const n=t.path==="",a=n?void 0:m.parseDataPath(t.path),r=n?s.matchAll():s.match(a.segments);for(const i of r){if(!i.active||i.node.disposed)continue;if(i.phase!==void 0){this._queue(i.phase,i.node,t);continue}const o=n?this._phaseRouter.matchAll():this._phaseRouter.match(a.segments);for(const l of o)this._queue(l.phase.name,i.node,t)}}this._pending.size!==0&&this._schedule()}}_queue(e,s,t){if(!this._phaseByName.has(e))return;let n=this._pending.get(e);n===void 0&&(n=new Map,this._pending.set(e,n)),u(n,s,[t])}_schedule(){if(this._running||this._scheduled||this._disposed)return;if(this._scheduler==="sync"){if(this._deferSync())return;this.flush();return}this._scheduled=!0;const e=++this._scheduleToken,s=()=>{this._disposed||!this._scheduled||e!==this._scheduleToken||(this._scheduled=!1,this._frameHandle=void 0,this._frameHandleKind=void 0,this.flush())};if(this._scheduler==="microtask"){queueMicrotask(s);return}typeof globalThis.requestAnimationFrame=="function"?(this._frameHandleKind="animation-frame",this._frameHandle=globalThis.requestAnimationFrame(s)):(this._frameHandleKind="timeout",this._frameHandle=setTimeout(s,16))}_cancelScheduled(){var e;this._scheduled&&(this._scheduled=!1,this._scheduleToken++,this._frameHandleKind==="animation-frame"&&this._frameHandle!==void 0?(e=globalThis.cancelAnimationFrame)==null||e.call(globalThis,this._frameHandle):this._frameHandleKind==="timeout"&&this._frameHandle!==void 0&&clearTimeout(this._frameHandle),this._frameHandle=void 0,this._frameHandleKind=void 0)}_nextFrame(){var t;const e=((t=globalThis.performance)==null?void 0:t.now())??Date.now();if(this._firstFrameAt===void 0||this._lastFrameAt===void 0)return this._firstFrameAt=e,this._lastFrameAt=e,this._frame=Object.freeze({now:e,delta:0,elapsed:0,frame:0});this._frameNumber++;const s=Object.freeze({now:e,delta:Math.min(Math.max(e-this._lastFrameAt,0),100),elapsed:Math.max(e-this._firstFrameAt,0),frame:this._frameNumber});return this._lastFrameAt=e,this._frame=s}_hasPending(){return this._pending.size!==0||this._tasks.size!==0}_expandContexts(e,s,t){const n=[...s.entries()].filter(([r])=>!r.disposed).sort(([r],[i])=>i.priority-r.priority),a=new Map;if(e.traversal==="dirty-only")for(const[r,i]of n)u(a,r,i.events);else if(e.traversal==="dirty-and-down")for(const[r,i]of n)g(r,o=>u(a,o,i.events));else if(e.traversal==="dirty-and-up")for(const[r,i]of n){let o=r;for(;o!==null&&o!==this._root;)u(a,o,i.events),o=o.parent}else{const r=[],i=new Set;for(const o of s.values())for(const l of o.events)i.has(l)||(i.add(l),r.push(l));for(const o of this._root.children)g(o,l=>u(a,l,r))}return[...a].filter(([r])=>{var i;return((i=e.nodes)==null?void 0:i.call(e,r))??!0}).map(([r,i])=>({events:i.events,frame:t,node:r,phase:e.name}))}_assertAlive(){if(this._disposed)throw new Error("[Raph] Phase pipeline is disposed.")}}function u(d,e,s){let t=d.get(e);t===void 0&&(t={events:[],seen:new Set},d.set(e,t));for(const n of s)t.seen.has(n)||(t.seen.add(n),t.events.push(n))}function g(d,e){e(d);for(const s of d.children)g(s,e)}function R(d){return d==="dirty-only"||d==="dirty-and-down"||d==="dirty-and-up"||d==="all"}function A(d){return d===void 0||d==="dirty"||d==="always"}exports.RaphPhasePipeline=P;
|
|
@@ -0,0 +1,526 @@
|
|
|
1
|
+
var w = Object.defineProperty;
|
|
2
|
+
var k = (d, e, s) => e in d ? w(d, e, { enumerable: !0, configurable: !0, writable: !0, value: s }) : d[e] = s;
|
|
3
|
+
var h = (d, e, s) => k(d, typeof e != "symbol" ? e + "" : e, s);
|
|
4
|
+
import { DataPath as g, parseDataPath as b } from "../path/data-path.js";
|
|
5
|
+
import { PathRouter as v } from "../path/path-router.js";
|
|
6
|
+
const y = 1e4, P = () => {
|
|
7
|
+
};
|
|
8
|
+
class M {
|
|
9
|
+
/**
|
|
10
|
+
* Создаёт phase pipeline для runtime и его root node.
|
|
11
|
+
*/
|
|
12
|
+
constructor(e, s, t, n, a = () => !1) {
|
|
13
|
+
// Индексируют data observers и phase definitions.
|
|
14
|
+
h(this, "_observerRouter");
|
|
15
|
+
h(this, "_phaseRouter", new v());
|
|
16
|
+
h(this, "_observers");
|
|
17
|
+
h(this, "_stopKernel");
|
|
18
|
+
h(this, "_phases", []);
|
|
19
|
+
h(this, "_phaseByName", /* @__PURE__ */ new Map());
|
|
20
|
+
// Хранят pending nodes, effect tasks и registration counters.
|
|
21
|
+
h(this, "_pending", /* @__PURE__ */ new Map());
|
|
22
|
+
h(this, "_tasks", /* @__PURE__ */ new Map());
|
|
23
|
+
h(this, "_phaseBindings", /* @__PURE__ */ new Map());
|
|
24
|
+
h(this, "_taskSequence", 0);
|
|
25
|
+
// Управляют выбранным scheduler и текущим flush lifecycle.
|
|
26
|
+
h(this, "_scheduled", !1);
|
|
27
|
+
h(this, "_scheduleToken", 0);
|
|
28
|
+
h(this, "_frameHandle");
|
|
29
|
+
h(this, "_frameHandleKind");
|
|
30
|
+
h(this, "_configurationLocked", !1);
|
|
31
|
+
h(this, "_running", !1);
|
|
32
|
+
h(this, "_disposed", !1);
|
|
33
|
+
// Формируют immutable frame context для phase callbacks.
|
|
34
|
+
h(this, "_firstFrameAt");
|
|
35
|
+
h(this, "_lastFrameAt");
|
|
36
|
+
h(this, "_frameNumber", 0);
|
|
37
|
+
h(this, "_frame", Object.freeze({ now: 0, delta: 0, elapsed: 0, frame: 0 }));
|
|
38
|
+
this._kernel = e, this._root = s, this._scheduler = t, this._runUntracked = n, this._deferSync = a;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Возвращает последний frame context pipeline.
|
|
42
|
+
*/
|
|
43
|
+
get frame() {
|
|
44
|
+
return this._frame;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Возвращает текущее упорядоченное определение phases.
|
|
48
|
+
*/
|
|
49
|
+
get phases() {
|
|
50
|
+
return this._phases.map((e) => e.phase);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Заменяет полное определение phase pipeline до его первого выполнения.
|
|
54
|
+
*/
|
|
55
|
+
definePhases(e) {
|
|
56
|
+
if (this._assertAlive(), this._configurationLocked || this._firstFrameAt !== void 0)
|
|
57
|
+
throw new Error("[Raph] Cannot redefine phases after phase pipeline execution has started.");
|
|
58
|
+
const s = /* @__PURE__ */ new Map(), t = new v(), n = [];
|
|
59
|
+
for (const a of e) {
|
|
60
|
+
const r = a.name.trim();
|
|
61
|
+
if (!r)
|
|
62
|
+
throw new Error("[Raph] Phase name must not be empty.");
|
|
63
|
+
if (s.has(r))
|
|
64
|
+
throw new Error(`[Raph] Duplicate phase name "${r}".`);
|
|
65
|
+
if (!R(a.traversal))
|
|
66
|
+
throw new Error(`[Raph] Unsupported phase traversal "${String(a.traversal)}".`);
|
|
67
|
+
if (!A(a.mode))
|
|
68
|
+
throw new Error(`[Raph] Unsupported phase mode "${String(a.mode)}".`);
|
|
69
|
+
if (a.each !== void 0 && typeof a.each != "function")
|
|
70
|
+
throw new TypeError(`[Raph] Phase "${r}" each executor must be a function.`);
|
|
71
|
+
if (a.all !== void 0 && typeof a.all != "function")
|
|
72
|
+
throw new TypeError(`[Raph] Phase "${r}" all executor must be a function.`);
|
|
73
|
+
if (a.each !== void 0 && a.all !== void 0)
|
|
74
|
+
throw new TypeError(`[Raph] Phase "${r}" cannot define both each and all executors.`);
|
|
75
|
+
const i = Object.freeze({
|
|
76
|
+
...a,
|
|
77
|
+
name: r,
|
|
78
|
+
mode: a.mode ?? "dirty",
|
|
79
|
+
routes: Object.freeze([...a.routes ?? []])
|
|
80
|
+
}), o = { phase: i };
|
|
81
|
+
n.push(o), s.set(r, o);
|
|
82
|
+
for (const l of i.routes)
|
|
83
|
+
t.add(g.from(l)._asMask(), o);
|
|
84
|
+
}
|
|
85
|
+
this._assertRetainedPhases(s), this._phases = n, this._phaseByName = s, this._phaseRouter = t;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Добавляет phase до первого выполнения pipeline.
|
|
89
|
+
*/
|
|
90
|
+
addPhase(e) {
|
|
91
|
+
this.definePhases([...this._phases.map((s) => s.phase), e]);
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Удаляет пользовательские phases до первого выполнения pipeline.
|
|
95
|
+
*/
|
|
96
|
+
clearPhases() {
|
|
97
|
+
this.definePhases([]);
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Возвращает phase либо отклоняет неизвестное имя.
|
|
101
|
+
*/
|
|
102
|
+
requirePhase(e) {
|
|
103
|
+
if (this._assertAlive(), !this._phaseByName.has(e))
|
|
104
|
+
throw new Error(`[Raph] Phase "${e}" is not defined.`);
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Фиксирует phase definitions перед синхронным выполнением вне flush.
|
|
108
|
+
*/
|
|
109
|
+
lockConfiguration() {
|
|
110
|
+
this._assertAlive(), this._configurationLocked = !0;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Удерживает определение фазы для idle registrations вне data observer/effect.
|
|
114
|
+
*/
|
|
115
|
+
retainPhase(e) {
|
|
116
|
+
this.requirePhase(e), this._phaseBindings.set(e, (this._phaseBindings.get(e) ?? 0) + 1);
|
|
117
|
+
let s = !0;
|
|
118
|
+
return () => {
|
|
119
|
+
if (!s)
|
|
120
|
+
return;
|
|
121
|
+
s = !1;
|
|
122
|
+
const t = (this._phaseBindings.get(e) ?? 1) - 1;
|
|
123
|
+
t === 0 ? this._phaseBindings.delete(e) : this._phaseBindings.set(e, t);
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Возвращает scheduler mode указанной phase.
|
|
128
|
+
*/
|
|
129
|
+
phaseMode(e) {
|
|
130
|
+
this._assertAlive();
|
|
131
|
+
const s = this._phaseByName.get(e);
|
|
132
|
+
if (s === void 0)
|
|
133
|
+
throw new Error(`[Raph] Phase "${e}" is not defined.`);
|
|
134
|
+
return s.phase.mode ?? "dirty";
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Связывает реактивный effect с phase scheduler.
|
|
138
|
+
*/
|
|
139
|
+
registerEffect(e) {
|
|
140
|
+
return this.requirePhase(e), P;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Один раз связывает watcher с task и callback.
|
|
144
|
+
* Повторные invalidations используют ту же task без hot-path поиска node и phase.
|
|
145
|
+
*/
|
|
146
|
+
bindEffect(e, s, t, n) {
|
|
147
|
+
const a = this.registerEffect(e), r = {
|
|
148
|
+
active: !0,
|
|
149
|
+
pending: !1,
|
|
150
|
+
persistent: !0,
|
|
151
|
+
priority: s,
|
|
152
|
+
sequence: 0,
|
|
153
|
+
run: t,
|
|
154
|
+
node: n
|
|
155
|
+
};
|
|
156
|
+
return {
|
|
157
|
+
schedule: () => {
|
|
158
|
+
if (!r.active || r.pending || this._disposed || n != null && n.disposed)
|
|
159
|
+
return;
|
|
160
|
+
r.pending = !0, r.sequence = this._taskSequence++;
|
|
161
|
+
let i = this._tasks.get(e);
|
|
162
|
+
i === void 0 && (i = [], this._tasks.set(e, i)), i.push(r), this._schedule();
|
|
163
|
+
},
|
|
164
|
+
dispose: () => {
|
|
165
|
+
if (!r.active)
|
|
166
|
+
return;
|
|
167
|
+
r.active = !1, r.pending = !1, a();
|
|
168
|
+
const i = this._tasks.get(e);
|
|
169
|
+
if (i !== void 0) {
|
|
170
|
+
const o = i.indexOf(r);
|
|
171
|
+
o !== -1 && i.splice(o, 1), i.length === 0 && this._tasks.delete(e);
|
|
172
|
+
}
|
|
173
|
+
this._hasPending() || this._cancelScheduled();
|
|
174
|
+
}
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Ставит уже зарегистрированный effect в очередь его phase.
|
|
179
|
+
*/
|
|
180
|
+
queueEffect(e, s, t, n = !0) {
|
|
181
|
+
this.requirePhase(e);
|
|
182
|
+
const a = {
|
|
183
|
+
active: !0,
|
|
184
|
+
pending: !0,
|
|
185
|
+
persistent: !1,
|
|
186
|
+
priority: s,
|
|
187
|
+
sequence: this._taskSequence++,
|
|
188
|
+
run: t
|
|
189
|
+
};
|
|
190
|
+
let r = this._tasks.get(e);
|
|
191
|
+
return r === void 0 && (r = [], this._tasks.set(e, r)), r.push(a), n && this._schedule(), () => {
|
|
192
|
+
if (!a.active)
|
|
193
|
+
return;
|
|
194
|
+
a.active = !1;
|
|
195
|
+
const i = this._tasks.get(e);
|
|
196
|
+
if (i !== void 0) {
|
|
197
|
+
const o = i.indexOf(a);
|
|
198
|
+
o >= 0 && i.splice(o, 1), i.length === 0 && this._tasks.delete(e);
|
|
199
|
+
}
|
|
200
|
+
this._hasPending() || this._cancelScheduled();
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Запрашивает выполнение pipeline согласно scheduler mode.
|
|
205
|
+
*/
|
|
206
|
+
request() {
|
|
207
|
+
this._assertAlive(), this._hasPending() && this._schedule();
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Ставит frame-driven обход всего дерева в очередь даже без reactive effect.
|
|
211
|
+
*/
|
|
212
|
+
requestAlwaysPhases() {
|
|
213
|
+
this._assertAlive();
|
|
214
|
+
for (const e of this._phases) {
|
|
215
|
+
const s = e.phase;
|
|
216
|
+
if (s.mode !== "always" || s.traversal !== "all" || s.all === void 0)
|
|
217
|
+
continue;
|
|
218
|
+
let t = this._pending.get(s.name);
|
|
219
|
+
t === void 0 && (t = /* @__PURE__ */ new Map(), this._pending.set(s.name, t)), u(t, this._root, []);
|
|
220
|
+
}
|
|
221
|
+
this._pending.size !== 0 && this._schedule();
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Регистрирует path observer в phase pipeline.
|
|
225
|
+
*/
|
|
226
|
+
observeData(e, s, t) {
|
|
227
|
+
const n = t.phase.trim();
|
|
228
|
+
if (!this._phaseByName.has(n))
|
|
229
|
+
throw new Error(`[Raph] Phase "${n}" is not defined.`);
|
|
230
|
+
return this._addObserver(e, s, n, t);
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Регистрирует tracked executor указанной phase.
|
|
234
|
+
*/
|
|
235
|
+
track(e, s, t) {
|
|
236
|
+
return this._addObserver(e, s, void 0, t);
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Помечает node и зависимых владельцев как требующих выполнения.
|
|
240
|
+
*/
|
|
241
|
+
invalidate(e, s) {
|
|
242
|
+
this.requirePhase(s);
|
|
243
|
+
let t = this._pending.get(s);
|
|
244
|
+
t === void 0 && (t = /* @__PURE__ */ new Map(), this._pending.set(s, t)), u(t, e, []), this._schedule();
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Синхронно выполняет все готовые очереди pipeline.
|
|
248
|
+
*/
|
|
249
|
+
flush() {
|
|
250
|
+
var n;
|
|
251
|
+
if (this._assertAlive(), this._cancelScheduled(), this._running || !this._hasPending())
|
|
252
|
+
return;
|
|
253
|
+
this._running = !0;
|
|
254
|
+
const e = [], s = this._nextFrame();
|
|
255
|
+
let t = 0;
|
|
256
|
+
try {
|
|
257
|
+
for (; this._hasPending() && !this._disposed; ) {
|
|
258
|
+
if (++t > y) {
|
|
259
|
+
this._pending.clear();
|
|
260
|
+
for (const i of this._tasks.values())
|
|
261
|
+
for (const o of i)
|
|
262
|
+
o.active = !1;
|
|
263
|
+
throw this._tasks.clear(), new Error("[Raph] Phase flush exceeded 10000 passes.");
|
|
264
|
+
}
|
|
265
|
+
const a = this._pending;
|
|
266
|
+
this._pending = /* @__PURE__ */ new Map();
|
|
267
|
+
const r = this._tasks;
|
|
268
|
+
this._tasks = /* @__PURE__ */ new Map();
|
|
269
|
+
for (const i of this._phases) {
|
|
270
|
+
if (this._disposed)
|
|
271
|
+
break;
|
|
272
|
+
const o = i.phase.name, l = a.get(o);
|
|
273
|
+
if (l !== void 0 && l.size !== 0) {
|
|
274
|
+
const f = this._expandContexts(i.phase, l, s);
|
|
275
|
+
if (i.phase.each !== void 0)
|
|
276
|
+
for (const c of f) {
|
|
277
|
+
if (this._disposed)
|
|
278
|
+
break;
|
|
279
|
+
if (!c.node.disposed)
|
|
280
|
+
try {
|
|
281
|
+
this._runUntracked(() => i.phase.each(c));
|
|
282
|
+
} catch (p) {
|
|
283
|
+
e.push(p);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
else if (i.phase.all !== void 0 && !this._disposed)
|
|
287
|
+
try {
|
|
288
|
+
this._runUntracked(() => i.phase.all(f));
|
|
289
|
+
} catch (c) {
|
|
290
|
+
e.push(c);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
if (this._disposed)
|
|
294
|
+
break;
|
|
295
|
+
const _ = r.get(o);
|
|
296
|
+
if (!(_ === void 0 || _.length === 0)) {
|
|
297
|
+
_.length > 1 && _.sort(
|
|
298
|
+
(f, c) => c.priority - f.priority || f.sequence - c.sequence
|
|
299
|
+
);
|
|
300
|
+
for (const f of _) {
|
|
301
|
+
if (this._disposed)
|
|
302
|
+
break;
|
|
303
|
+
if (!(!f.active || !f.pending || (n = f.node) != null && n.disposed)) {
|
|
304
|
+
f.pending = !1, f.persistent || (f.active = !1);
|
|
305
|
+
try {
|
|
306
|
+
f.run();
|
|
307
|
+
} catch (c) {
|
|
308
|
+
e.push(c);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
} finally {
|
|
316
|
+
this._running = !1;
|
|
317
|
+
}
|
|
318
|
+
if (e.length === 1)
|
|
319
|
+
throw e[0];
|
|
320
|
+
if (e.length > 1)
|
|
321
|
+
throw new AggregateError(e, "[Raph] Multiple phase executors failed.");
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* Останавливает scheduler и удаляет observers, tasks и phase definitions.
|
|
325
|
+
*/
|
|
326
|
+
dispose() {
|
|
327
|
+
var e;
|
|
328
|
+
if (!this._disposed) {
|
|
329
|
+
this._disposed = !0, this._cancelScheduled(), this._pending.clear();
|
|
330
|
+
for (const s of this._tasks.values())
|
|
331
|
+
for (const t of s)
|
|
332
|
+
t.active = !1;
|
|
333
|
+
if (this._tasks.clear(), this._phaseBindings.clear(), (e = this._stopKernel) == null || e.call(this), this._stopKernel = void 0, this._observers !== void 0) {
|
|
334
|
+
for (const s of this._observers) {
|
|
335
|
+
s.active = !1;
|
|
336
|
+
for (const t of s.removeRoutes)
|
|
337
|
+
t();
|
|
338
|
+
}
|
|
339
|
+
this._observers.clear(), this._observers = void 0;
|
|
340
|
+
}
|
|
341
|
+
this._observerRouter = void 0, this._phases = [], this._phaseByName.clear(), this._phaseRouter = new v();
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* Показывает наличие запланированной или выполняемой работы pipeline.
|
|
346
|
+
* @internal
|
|
347
|
+
*/
|
|
348
|
+
_debugPending() {
|
|
349
|
+
return this._scheduled || this._running || this._hasPending();
|
|
350
|
+
}
|
|
351
|
+
_addObserver(e, s, t, n) {
|
|
352
|
+
this._assertAlive();
|
|
353
|
+
const a = Array.isArray(s) ? s : [s];
|
|
354
|
+
if (a.length === 0)
|
|
355
|
+
throw new TypeError("[Raph] Phase observer requires at least one mask.");
|
|
356
|
+
const r = /* @__PURE__ */ new Map();
|
|
357
|
+
for (const c of a) {
|
|
358
|
+
const p = g.from(c, n)._asMask();
|
|
359
|
+
r.set(p.canonical, p);
|
|
360
|
+
}
|
|
361
|
+
const i = this._observerRouter ?? (this._observerRouter = new v()), o = {
|
|
362
|
+
active: !0,
|
|
363
|
+
node: e,
|
|
364
|
+
...t === void 0 ? {} : { phase: t },
|
|
365
|
+
removeRoutes: []
|
|
366
|
+
}, l = [...r.values()].map((c) => i.add(c, o));
|
|
367
|
+
o.removeRoutes = l;
|
|
368
|
+
const _ = this._observers ?? (this._observers = /* @__PURE__ */ new Set());
|
|
369
|
+
_.add(o), this._ensureKernelWatch();
|
|
370
|
+
let f = !0;
|
|
371
|
+
return () => {
|
|
372
|
+
var c;
|
|
373
|
+
if (f) {
|
|
374
|
+
f = !1, o.active = !1;
|
|
375
|
+
for (const p of o.removeRoutes)
|
|
376
|
+
p();
|
|
377
|
+
_.delete(o), _.size === 0 && (this._observers = void 0, this._observerRouter = void 0, (c = this._stopKernel) == null || c.call(this), this._stopKernel = void 0);
|
|
378
|
+
}
|
|
379
|
+
};
|
|
380
|
+
}
|
|
381
|
+
_ensureKernelWatch() {
|
|
382
|
+
this._stopKernel ?? (this._stopKernel = this._kernel.watch("*", ({ events: e }) => {
|
|
383
|
+
this._receive(e);
|
|
384
|
+
}));
|
|
385
|
+
}
|
|
386
|
+
_assertRetainedPhases(e) {
|
|
387
|
+
for (const s of this._phaseBindings.keys())
|
|
388
|
+
if (!e.has(s))
|
|
389
|
+
throw new Error(`[Raph] Cannot remove phase "${s}" while it is still bound.`);
|
|
390
|
+
for (const s of this._observers ?? []) {
|
|
391
|
+
const t = s.phase;
|
|
392
|
+
if (s.active && t !== void 0 && !e.has(t))
|
|
393
|
+
throw new Error(`[Raph] Cannot remove phase "${t}" while it is still observed.`);
|
|
394
|
+
}
|
|
395
|
+
for (const s of this._pending.keys())
|
|
396
|
+
if (!e.has(s))
|
|
397
|
+
throw new Error(`[Raph] Cannot remove phase "${s}" while it has pending work.`);
|
|
398
|
+
for (const s of this._tasks.keys())
|
|
399
|
+
if (!e.has(s))
|
|
400
|
+
throw new Error(`[Raph] Cannot remove phase "${s}" while it has queued effects.`);
|
|
401
|
+
}
|
|
402
|
+
_receive(e) {
|
|
403
|
+
if (this._disposed)
|
|
404
|
+
return;
|
|
405
|
+
const s = this._observerRouter;
|
|
406
|
+
if (s !== void 0) {
|
|
407
|
+
for (const t of e) {
|
|
408
|
+
const n = t.path === "", a = n ? void 0 : b(t.path), r = n ? s.matchAll() : s.match(a.segments);
|
|
409
|
+
for (const i of r) {
|
|
410
|
+
if (!i.active || i.node.disposed)
|
|
411
|
+
continue;
|
|
412
|
+
if (i.phase !== void 0) {
|
|
413
|
+
this._queue(i.phase, i.node, t);
|
|
414
|
+
continue;
|
|
415
|
+
}
|
|
416
|
+
const o = n ? this._phaseRouter.matchAll() : this._phaseRouter.match(a.segments);
|
|
417
|
+
for (const l of o)
|
|
418
|
+
this._queue(l.phase.name, i.node, t);
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
this._pending.size !== 0 && this._schedule();
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
_queue(e, s, t) {
|
|
425
|
+
if (!this._phaseByName.has(e))
|
|
426
|
+
return;
|
|
427
|
+
let n = this._pending.get(e);
|
|
428
|
+
n === void 0 && (n = /* @__PURE__ */ new Map(), this._pending.set(e, n)), u(n, s, [t]);
|
|
429
|
+
}
|
|
430
|
+
_schedule() {
|
|
431
|
+
if (this._running || this._scheduled || this._disposed)
|
|
432
|
+
return;
|
|
433
|
+
if (this._scheduler === "sync") {
|
|
434
|
+
if (this._deferSync())
|
|
435
|
+
return;
|
|
436
|
+
this.flush();
|
|
437
|
+
return;
|
|
438
|
+
}
|
|
439
|
+
this._scheduled = !0;
|
|
440
|
+
const e = ++this._scheduleToken, s = () => {
|
|
441
|
+
this._disposed || !this._scheduled || e !== this._scheduleToken || (this._scheduled = !1, this._frameHandle = void 0, this._frameHandleKind = void 0, this.flush());
|
|
442
|
+
};
|
|
443
|
+
if (this._scheduler === "microtask") {
|
|
444
|
+
queueMicrotask(s);
|
|
445
|
+
return;
|
|
446
|
+
}
|
|
447
|
+
typeof globalThis.requestAnimationFrame == "function" ? (this._frameHandleKind = "animation-frame", this._frameHandle = globalThis.requestAnimationFrame(s)) : (this._frameHandleKind = "timeout", this._frameHandle = setTimeout(s, 16));
|
|
448
|
+
}
|
|
449
|
+
_cancelScheduled() {
|
|
450
|
+
var e;
|
|
451
|
+
this._scheduled && (this._scheduled = !1, this._scheduleToken++, this._frameHandleKind === "animation-frame" && this._frameHandle !== void 0 ? (e = globalThis.cancelAnimationFrame) == null || e.call(globalThis, this._frameHandle) : this._frameHandleKind === "timeout" && this._frameHandle !== void 0 && clearTimeout(this._frameHandle), this._frameHandle = void 0, this._frameHandleKind = void 0);
|
|
452
|
+
}
|
|
453
|
+
_nextFrame() {
|
|
454
|
+
var t;
|
|
455
|
+
const e = ((t = globalThis.performance) == null ? void 0 : t.now()) ?? Date.now();
|
|
456
|
+
if (this._firstFrameAt === void 0 || this._lastFrameAt === void 0)
|
|
457
|
+
return this._firstFrameAt = e, this._lastFrameAt = e, this._frame = Object.freeze({ now: e, delta: 0, elapsed: 0, frame: 0 });
|
|
458
|
+
this._frameNumber++;
|
|
459
|
+
const s = Object.freeze({
|
|
460
|
+
now: e,
|
|
461
|
+
delta: Math.min(Math.max(e - this._lastFrameAt, 0), 100),
|
|
462
|
+
elapsed: Math.max(e - this._firstFrameAt, 0),
|
|
463
|
+
frame: this._frameNumber
|
|
464
|
+
});
|
|
465
|
+
return this._lastFrameAt = e, this._frame = s;
|
|
466
|
+
}
|
|
467
|
+
_hasPending() {
|
|
468
|
+
return this._pending.size !== 0 || this._tasks.size !== 0;
|
|
469
|
+
}
|
|
470
|
+
_expandContexts(e, s, t) {
|
|
471
|
+
const n = [...s.entries()].filter(([r]) => !r.disposed).sort(([r], [i]) => i.priority - r.priority), a = /* @__PURE__ */ new Map();
|
|
472
|
+
if (e.traversal === "dirty-only")
|
|
473
|
+
for (const [r, i] of n)
|
|
474
|
+
u(a, r, i.events);
|
|
475
|
+
else if (e.traversal === "dirty-and-down")
|
|
476
|
+
for (const [r, i] of n)
|
|
477
|
+
m(r, (o) => u(a, o, i.events));
|
|
478
|
+
else if (e.traversal === "dirty-and-up")
|
|
479
|
+
for (const [r, i] of n) {
|
|
480
|
+
let o = r;
|
|
481
|
+
for (; o !== null && o !== this._root; )
|
|
482
|
+
u(a, o, i.events), o = o.parent;
|
|
483
|
+
}
|
|
484
|
+
else {
|
|
485
|
+
const r = [], i = /* @__PURE__ */ new Set();
|
|
486
|
+
for (const o of s.values())
|
|
487
|
+
for (const l of o.events)
|
|
488
|
+
i.has(l) || (i.add(l), r.push(l));
|
|
489
|
+
for (const o of this._root.children)
|
|
490
|
+
m(o, (l) => u(a, l, r));
|
|
491
|
+
}
|
|
492
|
+
return [...a].filter(([r]) => {
|
|
493
|
+
var i;
|
|
494
|
+
return ((i = e.nodes) == null ? void 0 : i.call(e, r)) ?? !0;
|
|
495
|
+
}).map(([r, i]) => ({
|
|
496
|
+
events: i.events,
|
|
497
|
+
frame: t,
|
|
498
|
+
node: r,
|
|
499
|
+
phase: e.name
|
|
500
|
+
}));
|
|
501
|
+
}
|
|
502
|
+
_assertAlive() {
|
|
503
|
+
if (this._disposed)
|
|
504
|
+
throw new Error("[Raph] Phase pipeline is disposed.");
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
function u(d, e, s) {
|
|
508
|
+
let t = d.get(e);
|
|
509
|
+
t === void 0 && (t = { events: [], seen: /* @__PURE__ */ new Set() }, d.set(e, t));
|
|
510
|
+
for (const n of s)
|
|
511
|
+
t.seen.has(n) || (t.seen.add(n), t.events.push(n));
|
|
512
|
+
}
|
|
513
|
+
function m(d, e) {
|
|
514
|
+
e(d);
|
|
515
|
+
for (const s of d.children)
|
|
516
|
+
m(s, e);
|
|
517
|
+
}
|
|
518
|
+
function R(d) {
|
|
519
|
+
return d === "dirty-only" || d === "dirty-and-down" || d === "dirty-and-up" || d === "all";
|
|
520
|
+
}
|
|
521
|
+
function A(d) {
|
|
522
|
+
return d === void 0 || d === "dirty" || d === "always";
|
|
523
|
+
}
|
|
524
|
+
export {
|
|
525
|
+
M as RaphPhasePipeline
|
|
526
|
+
};
|