@dimina-kit/electron-deck 0.1.0-dev.20260701083540 → 0.1.0-dev.20260701155140
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client/index.d.ts +2 -0
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +92 -12
- package/dist/client/index.js.map +1 -1
- package/dist/client/layout-client.d.ts +35 -14
- package/dist/client/layout-client.d.ts.map +1 -1
- package/dist/client/placement-publisher.d.ts +14 -0
- package/dist/client/placement-publisher.d.ts.map +1 -0
- package/dist/dock-react/index.js +1 -1
- package/dist/{electron-deck-C9_Yu3fd.js → electron-deck-B9fun93z.js} +105 -78
- package/dist/electron-deck-B9fun93z.js.map +1 -0
- package/dist/host/index.js +1 -1
- package/dist/index.js +1 -1
- package/dist/internal/deck-app.d.ts +43 -11
- package/dist/internal/deck-app.d.ts.map +1 -1
- package/dist/internal/wire-transport.d.ts +17 -14
- package/dist/internal/wire-transport.d.ts.map +1 -1
- package/dist/layout/index.d.ts +4 -0
- package/dist/layout/index.d.ts.map +1 -1
- package/dist/layout/index.js +2 -2
- package/dist/layout/placement-reconcile.d.ts +50 -0
- package/dist/layout/placement-reconcile.d.ts.map +1 -0
- package/dist/layout/snapshot-reconcile.d.ts +28 -0
- package/dist/layout/snapshot-reconcile.d.ts.map +1 -0
- package/dist/{layout-B1t15b_q.js → layout-ByOiOdnc.js} +267 -2
- package/dist/layout-ByOiOdnc.js.map +1 -0
- package/dist/main/index.js +1 -1
- package/dist/main/view-handle.d.ts.map +1 -1
- package/dist/preload/index.cjs +4 -4
- package/dist/preload/index.cjs.map +1 -1
- package/dist/preload/index.d.ts +1 -1
- package/dist/preload/index.js +4 -4
- package/dist/preload/index.js.map +1 -1
- package/dist/{protocol-BJqo-vP2.js → protocol-B6TOT9AP.js} +2 -2
- package/dist/protocol-B6TOT9AP.js.map +1 -0
- package/dist/shared/protocol.d.ts +1 -1
- package/dist/{view-handle-CR-yWNfr.js → view-handle-DDhpBuW-.js} +2 -2
- package/dist/{view-handle-CR-yWNfr.js.map → view-handle-DDhpBuW-.js.map} +1 -1
- package/package.json +4 -4
- package/dist/electron-deck-C9_Yu3fd.js.map +0 -1
- package/dist/layout-B1t15b_q.js.map +0 -1
- package/dist/protocol-BJqo-vP2.js.map +0 -1
|
@@ -143,12 +143,31 @@ export declare class DeckApp {
|
|
|
143
143
|
/**
|
|
144
144
|
* slot-token registry (view-handle.md「slot-token 握手」/ capability-and-lifecycle.md「anchor slotToken 原子下发」):
|
|
145
145
|
* each anchored `placeIn` mints an unguessable token bound to (viewId, slotId,
|
|
146
|
-
* authorizedWcId). The `__electron-deck:
|
|
147
|
-
*
|
|
148
|
-
*
|
|
146
|
+
* authorizedWcId, zone). The `__electron-deck:snapshot` apply path authorizes
|
|
147
|
+
* each of the renderer's per-view tokens (token known AND authorized to the
|
|
148
|
+
* sender wc), DERIVES the view's identity (viewId) + z-order (zone→layer) from
|
|
149
|
+
* this registry (never trusting the renderer-reported fields), reconciles the
|
|
150
|
+
* cleaned window-level table, and drives each view's `apply`. `resend` re-pushes
|
|
151
|
+
* the slot-grant (layout-subscribe replay).
|
|
149
152
|
*/
|
|
150
153
|
private readonly slotTokens;
|
|
151
154
|
private slotSeq;
|
|
155
|
+
/**
|
|
156
|
+
* Per-control-wc level-triggered reconciler state (keyed by authorizedWcId).
|
|
157
|
+
* The renderer publishes a whole window-level desired-placement table each
|
|
158
|
+
* frame; `reconcile` diffs it against the last-applied actual and emits ops, so
|
|
159
|
+
* a lost or spurious per-view edge self-corrects instead of sticking a view
|
|
160
|
+
* detached (the white-screen failure mode). Reset on layout-subscribe (reload)
|
|
161
|
+
* and dropped on wc revoke.
|
|
162
|
+
*/
|
|
163
|
+
private readonly reconcileStates;
|
|
164
|
+
/**
|
|
165
|
+
* Per-control-wc strictly-monotonic generation counter. Bumped on every
|
|
166
|
+
* layout-subscribe and stamped into each slot-grant, so a reload's higher
|
|
167
|
+
* generation resets the reconciler regardless of IPC ordering (a late in-flight
|
|
168
|
+
* pre-reload snapshot carries a lower generation → rejected).
|
|
169
|
+
*/
|
|
170
|
+
private readonly perWcGeneration;
|
|
152
171
|
private _runtime;
|
|
153
172
|
private startCalled;
|
|
154
173
|
private shutdownPromise;
|
|
@@ -374,19 +393,32 @@ export declare class DeckApp {
|
|
|
374
393
|
*/
|
|
375
394
|
private ensureSlotChannelsArmed;
|
|
376
395
|
/**
|
|
377
|
-
* slot-token apply path (`__electron-deck:
|
|
378
|
-
*
|
|
379
|
-
*
|
|
396
|
+
* slot-token apply path (`__electron-deck:snapshot`). The renderer publishes a
|
|
397
|
+
* whole window-level desired-placement table; each entry's slotToken is the
|
|
398
|
+
* credential. Steps:
|
|
399
|
+
* 1. AUTHORIZE + clean: `cleanSnapshot` keeps only views whose token is known
|
|
400
|
+
* AND authorized to `senderId` (anti-spoof), deriving each view's identity
|
|
401
|
+
* (viewId) + z-order (zone→layer) from the registry — never from the
|
|
402
|
+
* renderer-reported fields. A non-empty snapshot that fully fails
|
|
403
|
+
* authorization is rejected wholesale (returns null) so a transient token
|
|
404
|
+
* failure is NOT read as "detach everything".
|
|
405
|
+
* 2. RECONCILE the cleaned table against this wc's last-applied actual state
|
|
406
|
+
* → an ordered op list (level-triggered; a lost/spurious frame self-heals).
|
|
407
|
+
* 3. DISPATCH the ops onto each view's `applyPlacement` sink.
|
|
380
408
|
*/
|
|
381
|
-
private
|
|
409
|
+
private handleSnapshot;
|
|
382
410
|
/**
|
|
383
411
|
* Per-wc layout-subscribe replay (`__electron-deck:layout-subscribe`). When the
|
|
384
|
-
* authorized control wc (re)subscribes (e.g. after reload),
|
|
385
|
-
*
|
|
386
|
-
*
|
|
412
|
+
* authorized control wc (re)subscribes (e.g. after reload), BUMP its generation
|
|
413
|
+
* and RESET its reconciler (a reload restarts the renderer's epoch at 0; without
|
|
414
|
+
* the reset the fresh low-epoch snapshots would be rejected as stale), then
|
|
415
|
+
* re-push every grant it owns — now carrying the bumped generation — so it can
|
|
416
|
+
* re-bind its DOM slots. A DIFFERENT wc's subscribe never touches another wc's
|
|
417
|
+
* state or grants.
|
|
387
418
|
*/
|
|
388
419
|
private handleLayoutSubscribe;
|
|
389
|
-
/** Drop every slot token authorized to `wcId`
|
|
420
|
+
/** Drop every slot token + reconciler/generation state authorized to `wcId`
|
|
421
|
+
* (window-close / shutdown hygiene). */
|
|
390
422
|
private revokeSlotTokensForWc;
|
|
391
423
|
private handleSubWindowClosed;
|
|
392
424
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deck-app.d.ts","sourceRoot":"","sources":["../../src/internal/deck-app.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACX,UAAU,EAIV,cAAc,EACd,OAAO,EACP,YAAY,EAIZ,UAAU,EASV,MAAM,aAAa,CAAA;AAIpB,OAAO,KAAK,EAEX,oBAAoB,EAEpB,eAAe,EAGf,MAAM,qBAAqB,CAAA;AAM5B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AAE5D,OAAO,EAAe,KAAK,KAAK,EAAE,MAAM,kBAAkB,CAAA;
|
|
1
|
+
{"version":3,"file":"deck-app.d.ts","sourceRoot":"","sources":["../../src/internal/deck-app.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACX,UAAU,EAIV,cAAc,EACd,OAAO,EACP,YAAY,EAIZ,UAAU,EASV,MAAM,aAAa,CAAA;AAIpB,OAAO,KAAK,EAEX,oBAAoB,EAEpB,eAAe,EAGf,MAAM,qBAAqB,CAAA;AAM5B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AAE5D,OAAO,EAAe,KAAK,KAAK,EAAE,MAAM,kBAAkB,CAAA;AAe1D,OAAO,EAEN,KAAK,gBAAgB,EACrB,MAAM,uBAAuB,CAAA;AAK9B,OAAO,EAEN,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACvB,MAAM,qBAAqB,CAAA;AAQ5B;;;;;;GAMG;AACH,MAAM,WAAW,cAAc;IAC9B,QAAQ,CAAC,aAAa,CAAC,EAAE;QACxB,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAA;QAChC,2DAA2D;QAC3D,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,SAAS,kBAAkB,EAAE,CAAA;QACjE,4CAA4C;QAC5C,QAAQ,CAAC,YAAY,CAAC,EAAE,YAAY,CAAA;KACpC,CAAA;IACD;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,eAAe,CAAA;IACnC;;;;OAIG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,cAAc,CAAA;CACjC;AAiDD;;;;;;;GAOG;AACH,qBAAa,OAAO;IACnB,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAA;IAE3B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAyB;IACnD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA6B;IACtD,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAiB;IACrC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAiC;IACrD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAoE;IAChG,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA6B;IACtD;6EACyE;IACzE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA6B;IACxD;;;;uEAImE;IACnE,OAAO,CAAC,UAAU,CAA0B;IAC5C;iFAC6E;IAC7E,OAAO,CAAC,QAAQ,CAAC,uBAAuB,CAA4C;IACpF,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAgB;IACxC,OAAO,CAAC,aAAa,CAA6B;IAClD;sFACkF;IAClF,OAAO,CAAC,gBAAgB,CAA4B;IACpD,OAAO,CAAC,UAAU,CAAoC;IACtD,OAAO,CAAC,WAAW,CAAsC;IACzD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAA0C;IAC1E,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAkC;IACjE;;;;;OAKG;IACH,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAuB;IACjD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAG5B;IACH;;;;;;;;OAQG;IACH,OAAO,CAAC,QAAQ,CAAC,SAAS,CAGvB;IACH,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAA6B;IAClE,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAA0B;IAC5D;;;;OAIG;IACH,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAA+C;IAChF;;;;;;OAMG;IACH,OAAO,CAAC,QAAQ,CAAC,cAAc,CAA4C;IAC3E;;;;;;;OAOG;IACH,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAWjC;IACH;wFACoF;IACpF,OAAO,CAAC,aAAa,CAAkC;IACvD,2DAA2D;IAC3D,OAAO,CAAC,OAAO,CAAI;IACnB;;;;;;;OAOG;IACH,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAoC;IAC7D;;;;;;;OAOG;IACH,OAAO,CAAC,QAAQ,CAAC,eAAe,CAG7B;IACH;;;oFAGgF;IAChF,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAoC;IACjE;;;;;;;;;OASG;IACH,OAAO,CAAC,QAAQ,CAAC,UAAU,CAGxB;IACH,OAAO,CAAC,OAAO,CAAI;IACnB;;;;;;;OAOG;IACH,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAqC;IACrE;;;;;OAKG;IACH,OAAO,CAAC,QAAQ,CAAC,eAAe,CAA4B;IAC5D,OAAO,CAAC,QAAQ,CAAuB;IACvC,OAAO,CAAC,WAAW,CAAQ;IAC3B,OAAO,CAAC,eAAe,CAA6B;IACpD;kFAC8E;IAC9E,OAAO,CAAC,aAAa,CAAQ;IAC7B,oFAAoF;IACpF,OAAO,CAAC,sBAAsB,CAAyC;IACvE;iFAC6E;IAC7E,OAAO,CAAC,YAAY,CAAQ;IAC5B;;;;;;;;;;;0EAWsE;IACtE,OAAO,CAAC,cAAc,CAA6B;gBAEvC,MAAM,EAAE,UAAU,EAAE,OAAO,GAAE,cAAmB;IAuB5D,IAAI,KAAK,IAAI,cAAc,CAE1B;IAED,IAAI,OAAO,IAAI,OAAO,CAKrB;IAEK,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAiF5B;;;;;;;OAOG;IACH,OAAO,CAAC,gBAAgB;IAwBxB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAMzB;;;;;;OAMG;IACH,iBAAiB,CAAC,EAAE,EAAE,kBAAkB,GAAG,UAAU;IAIrD;;;;;;;;;OASG;IACH,OAAO,CAAC,UAAU;IAkClB;;;;;;;;;;;;;;OAcG;IACH,OAAO,CAAC,wBAAwB;IA+BhC;;;;;;;OAOG;IACH,OAAO,CAAC,eAAe;IAmDvB;;;;;;;;OAQG;IACH,OAAO,CAAC,gBAAgB;IAQxB;;;;;;OAMG;YACW,sBAAsB;IAoBpC;;;;;;;;;OASG;IACH,OAAO,CAAC,wBAAwB;IA8BhC;;;OAGG;IACH,gBAAgB,IAAI,GAAG,CAAC,kBAAkB,EAAE;QAAE,MAAM,EAAE,oBAAoB,CAAC;QAAC,WAAW,EAAE,KAAK,CAAA;KAAE,CAAC;IAIjG,yCAAyC;IACzC,WAAW,IAAI,KAAK;IAIpB,kDAAkD;IAClD,WAAW,IAAI,GAAG,CAAC,kBAAkB,EAAE;QAAE,OAAO,EAAE,KAAK,CAAC;QAAC,MAAM,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC;QAAC,WAAW,EAAE,KAAK,CAAA;KAAE,CAAC;IAIvG,kEAAkE;IAClE,kBAAkB,IAAI,gBAAgB;IAItC;;;;OAIG;IACH,0BAA0B,IAAI,IAAI;IAiBlC,OAAO,CAAC,qBAAqB;IAoC7B;;;;;;OAMG;IACH,OAAO,CAAC,qBAAqB;IAmD7B,OAAO,CAAC,gBAAgB;IAoOxB,4FAA4F;IAC5F,OAAO,CAAC,oBAAoB;IAmB5B;;;;;OAKG;IACH,OAAO,CAAC,QAAQ;IAehB;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IASzB,OAAO,CAAC,iBAAiB;IAiGzB;;;;;;OAMG;IACH,OAAO,CAAC,uBAAuB;IAI/B;;;;OAIG;IACH,OAAO,CAAC,yBAAyB,CAAQ;IACzC,OAAO,CAAC,uBAAuB;IAS/B,OAAO,CAAC,eAAe;IAqFvB;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,OAAO,CAAC,WAAW;IAwGnB;;;;;;;;;;;;;;;OAeG;IACH,OAAO,CAAC,iBAAiB;IAczB;;;;;;;OAOG;IACH,OAAO,CAAC,uBAAuB;IAO/B;;;;;;;;;;;;;OAaG;IACH,OAAO,CAAC,cAAc;IAsBtB;;;;;;;;OAQG;IACH,OAAO,CAAC,qBAAqB;IAQ7B;6CACyC;IACzC,OAAO,CAAC,qBAAqB;IAQ7B,OAAO,CAAC,qBAAqB;IAuC7B;;;;;;;;OAQG;IACH,OAAO,CAAC,qBAAqB;IAmB7B,OAAO,CAAC,kBAAkB;YAiBZ,cAAc;YAOd,UAAU;IA8BxB,OAAO,CAAC,kBAAkB;YAYZ,iBAAiB;IA+E/B,OAAO,CAAC,YAAY;CAiqBpB"}
|
|
@@ -83,11 +83,13 @@ export interface WireTransportDeps {
|
|
|
83
83
|
*/
|
|
84
84
|
readonly declaredEvents: () => readonly string[];
|
|
85
85
|
/**
|
|
86
|
-
* OPTIONAL slot-token inbound: `__electron-deck:
|
|
87
|
-
* provided, `start()` registers the `
|
|
88
|
-
* gate as invoke). On gate pass → `
|
|
86
|
+
* OPTIONAL slot-token inbound: `__electron-deck:snapshot` apply path. When
|
|
87
|
+
* provided, `start()` registers the `Snapshot` handler (same trust + main-frame
|
|
88
|
+
* gate as invoke). On gate pass → `onSnapshot(senderId, rawSnapshot)`. The
|
|
89
|
+
* payload (the renderer's window-level placement table) is opaque here and
|
|
90
|
+
* authorized/validated downstream — the wire only enforces the trust boundary.
|
|
89
91
|
*/
|
|
90
|
-
readonly
|
|
92
|
+
readonly onSnapshot?: (senderId: number, rawSnapshot: unknown) => void;
|
|
91
93
|
/**
|
|
92
94
|
* OPTIONAL slot-token inbound: `__electron-deck:layout-subscribe` per-wc
|
|
93
95
|
* replay request. When provided, `start()` registers the `LayoutSubscribe`
|
|
@@ -99,21 +101,21 @@ export declare class WireTransport {
|
|
|
99
101
|
private readonly deps;
|
|
100
102
|
private state;
|
|
101
103
|
private busSubscription;
|
|
102
|
-
/** Whether the optional
|
|
104
|
+
/** Whether the optional Snapshot / LayoutSubscribe handlers were registered
|
|
103
105
|
* (either eagerly at start() via deps, or lazily via armSlotChannels) — so
|
|
104
106
|
* dispose() only removes channels it actually registered. */
|
|
105
|
-
private
|
|
107
|
+
private snapshotRegistered;
|
|
106
108
|
private layoutSubscribeRegistered;
|
|
107
109
|
/** Effective slot callbacks. Populated from deps at start() (eager path, used
|
|
108
110
|
* by the wire unit tests) OR by {@link armSlotChannels} (lazy path, used by
|
|
109
111
|
* deck-app so an app with no anchored views registers only Invoke + Probe). */
|
|
110
|
-
private
|
|
112
|
+
private onSnapshotCb;
|
|
111
113
|
private onLayoutSubscribeCb;
|
|
112
114
|
constructor(deps: WireTransportDeps);
|
|
113
115
|
start(): void;
|
|
114
116
|
private tryRemoveHandler;
|
|
115
|
-
private
|
|
116
|
-
private
|
|
117
|
+
private registerSnapshotHandler;
|
|
118
|
+
private unregisterSnapshotHandler;
|
|
117
119
|
private registerLayoutSubscribeHandler;
|
|
118
120
|
private unregisterLayoutSubscribeHandler;
|
|
119
121
|
/**
|
|
@@ -124,7 +126,7 @@ export declare class WireTransport {
|
|
|
124
126
|
* no anchored views never registers these channels (keeping the wire's
|
|
125
127
|
* handler footprint at Invoke + Probe until a slot is actually minted).
|
|
126
128
|
*/
|
|
127
|
-
armSlotChannels(
|
|
129
|
+
armSlotChannels(onSnapshot: (senderId: number, rawSnapshot: unknown) => void, onLayoutSubscribe: (senderId: number) => void): void;
|
|
128
130
|
dispose(): void;
|
|
129
131
|
private handleProbe;
|
|
130
132
|
/**
|
|
@@ -144,11 +146,12 @@ export declare class WireTransport {
|
|
|
144
146
|
private isMainFrameSender;
|
|
145
147
|
private handleInvoke;
|
|
146
148
|
/**
|
|
147
|
-
* `__electron-deck:
|
|
148
|
-
*
|
|
149
|
-
* sub-frame) → DROP silently
|
|
149
|
+
* `__electron-deck:snapshot` inbound. Same gate as {@link handleInvoke} (trust +
|
|
150
|
+
* main-frame). On any gate failure (non-object payload, untrusted sender,
|
|
151
|
+
* sub-frame) → DROP silently. The payload's inner shape is opaque to the wire —
|
|
152
|
+
* authorized + validated downstream.
|
|
150
153
|
*/
|
|
151
|
-
private
|
|
154
|
+
private handleSnapshot;
|
|
152
155
|
/**
|
|
153
156
|
* `__electron-deck:layout-subscribe` inbound. Same gate as {@link handleInvoke}.
|
|
154
157
|
* On gate pass → `onLayoutSubscribe(senderId)`; else DROP silently.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wire-transport.d.ts","sourceRoot":"","sources":["../../src/internal/wire-transport.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAcH,OAAO,KAAK,EAAc,SAAS,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AACtE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAE9C;;;GAGG;AACH,eAAO,MAAM,SAAS;;;;;IAKrB,kEAAkE;;CAEzD,CAAA;AAEV,2EAA2E;AAC3E,MAAM,WAAW,QAAQ;IACxB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;CAC1B;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,SAAS;IACzB,uFAAuF;IACvF,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,kGAAkG;IAClG,QAAQ,CAAC,WAAW,EAAE,QAAQ,GAAG,IAAI,CAAA;CACrC;AAED,MAAM,WAAW,cAAc;IAC9B,MAAM,CACL,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,CAKR,KAAK,EAAE;QAAE,MAAM,EAAE;YAAE,EAAE,EAAE,MAAM,CAAC;YAAC,SAAS,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAA;SAAE,CAAC;QAAC,WAAW,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAA;KAAE,EAC7F,GAAG,IAAI,EAAE,OAAO,EAAE,KACd,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,GAC7B,IAAI,CAAA;IACP,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;CACpC;AAED,MAAM,WAAW,kBAAkB;IAClC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,WAAW,IAAI,OAAO,CAAA;IACtB,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAAA;CAC7C;AAED,MAAM,WAAW,iBAAiB;IACjC,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAA;IAChC,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAA;IACtB,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAA;IACnC,sEAAsE;IACtE,QAAQ,CAAC,kBAAkB,EAAE,MAAM,SAAS,kBAAkB,EAAE,CAAA;IAChE;mEAC+D;IAC/D,QAAQ,CAAC,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,SAAS,EAAE,EAAE,GAAG,EAAE,SAAS,KAAK,OAAO,CAAC,SAAS,CAAC,CAAA;IACrG,yCAAyC;IACzC,QAAQ,CAAC,eAAe,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,SAAS,EAAE,EAAE,GAAG,EAAE,SAAS,KAAK,OAAO,CAAC,SAAS,CAAC,CAAA;IAC1G;;;;;;OAMG;IACH,QAAQ,CAAC,cAAc,EAAE,MAAM,SAAS,MAAM,EAAE,CAAA;IAChD
|
|
1
|
+
{"version":3,"file":"wire-transport.d.ts","sourceRoot":"","sources":["../../src/internal/wire-transport.ts"],"names":[],"mappings":"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"}
|
package/dist/layout/index.d.ts
CHANGED
|
@@ -12,4 +12,8 @@ export { sanitizeFlexibleWeights } from './sanitize.js';
|
|
|
12
12
|
export { setSizes, setConstraint, setActive, movePanel, splitPanel, closePanel, extractPanel, insertPanel, } from './mutations.js';
|
|
13
13
|
export { createLayoutModel } from './model.js';
|
|
14
14
|
export { closePanelForUser } from './user-actions.js';
|
|
15
|
+
export type { Bounds, Placement, DesiredView, PlacementSnapshot, ViewOp, ActualView, ReconcilerState, } from './placement-reconcile.js';
|
|
16
|
+
export { createInitialState, reconcile } from './placement-reconcile.js';
|
|
17
|
+
export type { CleanView, CleanSnapshot, Authorizer } from './snapshot-reconcile.js';
|
|
18
|
+
export { cleanSnapshot, dispatchOps } from './snapshot-reconcile.js';
|
|
15
19
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/layout/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,YAAY,EACX,WAAW,EACX,cAAc,EACd,SAAS,EACT,YAAY,EACZ,UAAU,EACV,UAAU,EACV,kBAAkB,EAClB,eAAe,EACf,qBAAqB,EACrB,iBAAiB,EACjB,eAAe,EACf,UAAU,EACV,aAAa,EACb,cAAc,EACd,WAAW,GACX,MAAM,YAAY,CAAA;AAEnB,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAA;AACnD,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAC3E,OAAO,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAA;AACvD,OAAO,EACN,QAAQ,EACR,aAAa,EACb,SAAS,EACT,SAAS,EACT,UAAU,EACV,UAAU,EACV,YAAY,EACZ,WAAW,GACX,MAAM,gBAAgB,CAAA;AACvB,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/layout/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,YAAY,EACX,WAAW,EACX,cAAc,EACd,SAAS,EACT,YAAY,EACZ,UAAU,EACV,UAAU,EACV,kBAAkB,EAClB,eAAe,EACf,qBAAqB,EACrB,iBAAiB,EACjB,eAAe,EACf,UAAU,EACV,aAAa,EACb,cAAc,EACd,WAAW,GACX,MAAM,YAAY,CAAA;AAEnB,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAA;AACnD,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAC3E,OAAO,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAA;AACvD,OAAO,EACN,QAAQ,EACR,aAAa,EACb,SAAS,EACT,SAAS,EACT,UAAU,EACV,UAAU,EACV,YAAY,EACZ,WAAW,GACX,MAAM,gBAAgB,CAAA;AACvB,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAErD,YAAY,EACX,MAAM,EACN,SAAS,EACT,WAAW,EACX,iBAAiB,EACjB,MAAM,EACN,UAAU,EACV,eAAe,GACf,MAAM,0BAA0B,CAAA;AACjC,OAAO,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAA;AAExE,YAAY,EAAE,SAAS,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAA;AACnF,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAA"}
|
package/dist/layout/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as
|
|
2
|
-
export { closePanel, closePanelForUser, createLayoutModel, createPanelRegistry, extractPanel, insertPanel, movePanel, parseLayout, sanitizeFlexibleWeights, serializeLayout, setActive, setConstraint, setSizes, splitPanel, validateTree };
|
|
1
|
+
import { _ as serializeLayout, a as closePanelForUser, c as extractPanel, d as setActive, f as setConstraint, g as parseLayout, h as sanitizeFlexibleWeights, i as reconcile, l as insertPanel, m as splitPanel, n as dispatchOps, o as createLayoutModel, p as setSizes, r as createInitialState, s as closePanel, t as cleanSnapshot, u as movePanel, v as validateTree, y as createPanelRegistry } from "../layout-ByOiOdnc.js";
|
|
2
|
+
export { cleanSnapshot, closePanel, closePanelForUser, createInitialState, createLayoutModel, createPanelRegistry, dispatchOps, extractPanel, insertPanel, movePanel, parseLayout, reconcile, sanitizeFlexibleWeights, serializeLayout, setActive, setConstraint, setSizes, splitPanel, validateTree };
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { Bounds, Placement } from '@dimina-kit/view-anchor';
|
|
2
|
+
export type { Bounds, Placement };
|
|
3
|
+
export interface DesiredView<Extra = unknown> {
|
|
4
|
+
viewId: string;
|
|
5
|
+
placement: Placement;
|
|
6
|
+
layer: number;
|
|
7
|
+
extra?: Extra;
|
|
8
|
+
}
|
|
9
|
+
export interface PlacementSnapshot<Extra = unknown> {
|
|
10
|
+
generation: number;
|
|
11
|
+
epoch: number;
|
|
12
|
+
views: DesiredView<Extra>[];
|
|
13
|
+
}
|
|
14
|
+
export type ViewOp<Extra = unknown> = {
|
|
15
|
+
kind: 'setBounds';
|
|
16
|
+
viewId: string;
|
|
17
|
+
bounds: Bounds;
|
|
18
|
+
extra?: Extra;
|
|
19
|
+
} | {
|
|
20
|
+
kind: 'attach';
|
|
21
|
+
viewId: string;
|
|
22
|
+
} | {
|
|
23
|
+
kind: 'setVisible';
|
|
24
|
+
viewId: string;
|
|
25
|
+
visible: boolean;
|
|
26
|
+
} | {
|
|
27
|
+
kind: 'detach';
|
|
28
|
+
viewId: string;
|
|
29
|
+
} | {
|
|
30
|
+
kind: 'reorder';
|
|
31
|
+
order: string[];
|
|
32
|
+
};
|
|
33
|
+
export interface ActualView<Extra = unknown> {
|
|
34
|
+
attached: boolean;
|
|
35
|
+
visible: boolean;
|
|
36
|
+
bounds?: Bounds;
|
|
37
|
+
extra?: Extra;
|
|
38
|
+
}
|
|
39
|
+
export interface ReconcilerState<Extra = unknown> {
|
|
40
|
+
generation: number;
|
|
41
|
+
lastEpoch: number;
|
|
42
|
+
desired: Map<string, DesiredView<Extra>>;
|
|
43
|
+
actual: Map<string, ActualView<Extra>>;
|
|
44
|
+
}
|
|
45
|
+
export declare function createInitialState<Extra = unknown>(): ReconcilerState<Extra>;
|
|
46
|
+
export declare function reconcile<Extra = unknown>(prev: ReconcilerState<Extra>, snapshot: PlacementSnapshot<Extra>): {
|
|
47
|
+
state: ReconcilerState<Extra>;
|
|
48
|
+
ops: ViewOp<Extra>[];
|
|
49
|
+
};
|
|
50
|
+
//# sourceMappingURL=placement-reconcile.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"placement-reconcile.d.ts","sourceRoot":"","sources":["../../src/layout/placement-reconcile.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AAEhE,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,CAAA;AAEjC,MAAM,WAAW,WAAW,CAAC,KAAK,GAAG,OAAO;IAC1C,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,SAAS,CAAA;IAEpB,KAAK,EAAE,MAAM,CAAA;IAEb,KAAK,CAAC,EAAE,KAAK,CAAA;CACd;AAED,MAAM,WAAW,iBAAiB,CAAC,KAAK,GAAG,OAAO;IAEhD,UAAU,EAAE,MAAM,CAAA;IAElB,KAAK,EAAE,MAAM,CAAA;IAEb,KAAK,EAAE,WAAW,CAAC,KAAK,CAAC,EAAE,CAAA;CAC5B;AAED,MAAM,MAAM,MAAM,CAAC,KAAK,GAAG,OAAO,IAC9B;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,KAAK,CAAA;CAAE,GACpE;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAClC;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,GACxD;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAClC;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,CAAA;AAExC,MAAM,WAAW,UAAU,CAAC,KAAK,GAAG,OAAO;IACzC,QAAQ,EAAE,OAAO,CAAA;IACjB,OAAO,EAAE,OAAO,CAAA;IAChB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,KAAK,CAAC,EAAE,KAAK,CAAA;CACd;AAED,MAAM,WAAW,eAAe,CAAC,KAAK,GAAG,OAAO;IAC9C,UAAU,EAAE,MAAM,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,KAAK,CAAC,CAAC,CAAA;IACxC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC,CAAA;CACvC;AAED,wBAAgB,kBAAkB,CAAC,KAAK,GAAG,OAAO,KAAK,eAAe,CAAC,KAAK,CAAC,CAO5E;AAiID,wBAAgB,SAAS,CAAC,KAAK,GAAG,OAAO,EACvC,IAAI,EAAE,eAAe,CAAC,KAAK,CAAC,EAC5B,QAAQ,EAAE,iBAAiB,CAAC,KAAK,CAAC,GACjC;IAAE,KAAK,EAAE,eAAe,CAAC,KAAK,CAAC,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,CAAA;CAAE,CA8CzD"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { Placement, ReconcilerState, ViewOp } from './placement-reconcile.js';
|
|
2
|
+
export interface CleanView {
|
|
3
|
+
viewId: string;
|
|
4
|
+
placement: Placement;
|
|
5
|
+
layer: number;
|
|
6
|
+
}
|
|
7
|
+
export interface CleanSnapshot {
|
|
8
|
+
generation: number;
|
|
9
|
+
epoch: number;
|
|
10
|
+
views: CleanView[];
|
|
11
|
+
}
|
|
12
|
+
export type Authorizer = (slotToken: string) => {
|
|
13
|
+
viewId: string;
|
|
14
|
+
layer: number;
|
|
15
|
+
} | null;
|
|
16
|
+
export declare function cleanSnapshot(raw: unknown, authorize: Authorizer): CleanSnapshot | null;
|
|
17
|
+
/**
|
|
18
|
+
* Collapse reconcile ops onto a two-state per-view sink. Gathers the viewIds any
|
|
19
|
+
* op touched (reorder excluded — deck z-order is compositor zone-fixed), then for
|
|
20
|
+
* each reads the reconciled end-state from `state.actual`: attached+visible+bounds
|
|
21
|
+
* → apply({visible:true,bounds}); otherwise apply({visible:false}). Reading from
|
|
22
|
+
* `actual` (not the op itself) means a bare restore still carries its bounds.
|
|
23
|
+
*
|
|
24
|
+
* Each apply runs in its own try/catch: one throwing sink (e.g. a destroyed native
|
|
25
|
+
* view) must not abort the rest of the dispatch.
|
|
26
|
+
*/
|
|
27
|
+
export declare function dispatchOps(ops: ViewOp[], state: ReconcilerState, resolveApply: (viewId: string) => ((p: Placement) => void) | null): void;
|
|
28
|
+
//# sourceMappingURL=snapshot-reconcile.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snapshot-reconcile.d.ts","sourceRoot":"","sources":["../../src/layout/snapshot-reconcile.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAU,SAAS,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAA;AAE1F,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,SAAS,CAAA;IACpB,KAAK,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAA;IAClB,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,SAAS,EAAE,CAAA;CACnB;AAMD,MAAM,MAAM,UAAU,GAAG,CAAC,SAAS,EAAE,MAAM,KAAK;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAA;AA2ExF,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,EAAE,SAAS,EAAE,UAAU,GAAG,aAAa,GAAG,IAAI,CAkBvF;AAED;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CACzB,GAAG,EAAE,MAAM,EAAE,EACb,KAAK,EAAE,eAAe,EACtB,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,CAAC,CAAC,CAAC,EAAE,SAAS,KAAK,IAAI,CAAC,GAAG,IAAI,GAChE,IAAI,CAoBN"}
|
|
@@ -614,6 +614,271 @@ function closePanelForUser(tree, panelId, registry) {
|
|
|
614
614
|
return registry.get(panelId)?.closable === false ? tree : closePanel(tree, panelId);
|
|
615
615
|
}
|
|
616
616
|
//#endregion
|
|
617
|
-
|
|
617
|
+
//#region src/layout/placement-reconcile.ts
|
|
618
|
+
function createInitialState() {
|
|
619
|
+
return {
|
|
620
|
+
generation: 0,
|
|
621
|
+
lastEpoch: -1,
|
|
622
|
+
desired: /* @__PURE__ */ new Map(),
|
|
623
|
+
actual: /* @__PURE__ */ new Map()
|
|
624
|
+
};
|
|
625
|
+
}
|
|
626
|
+
function roundBounds(b) {
|
|
627
|
+
return {
|
|
628
|
+
x: Math.round(b.x),
|
|
629
|
+
y: Math.round(b.y),
|
|
630
|
+
width: Math.round(b.width),
|
|
631
|
+
height: Math.round(b.height)
|
|
632
|
+
};
|
|
633
|
+
}
|
|
634
|
+
function sameBounds(a, b) {
|
|
635
|
+
if (a === void 0 || b === void 0) return a === b;
|
|
636
|
+
return a.x === b.x && a.y === b.y && a.width === b.width && a.height === b.height;
|
|
637
|
+
}
|
|
638
|
+
function sameExtra(a, b) {
|
|
639
|
+
if (a === b) return true;
|
|
640
|
+
if (a === void 0 || b === void 0) return false;
|
|
641
|
+
return JSON.stringify(a) === JSON.stringify(b);
|
|
642
|
+
}
|
|
643
|
+
function visibleBounds(dv) {
|
|
644
|
+
return roundBounds(dv.placement.bounds);
|
|
645
|
+
}
|
|
646
|
+
function setBoundsOp(id, dv) {
|
|
647
|
+
return {
|
|
648
|
+
kind: "setBounds",
|
|
649
|
+
viewId: id,
|
|
650
|
+
bounds: visibleBounds(dv),
|
|
651
|
+
...dv.extra !== void 0 ? { extra: dv.extra } : {}
|
|
652
|
+
};
|
|
653
|
+
}
|
|
654
|
+
function computeOrder(actual, desired) {
|
|
655
|
+
const attached = [...actual.entries()].filter(([, a]) => a.attached).map(([id]) => id);
|
|
656
|
+
attached.sort((id1, id2) => {
|
|
657
|
+
const l1 = desired.get(id1)?.layer ?? 0;
|
|
658
|
+
const l2 = desired.get(id2)?.layer ?? 0;
|
|
659
|
+
if (l1 !== l2) return l1 - l2;
|
|
660
|
+
return id1 < id2 ? -1 : id1 > id2 ? 1 : 0;
|
|
661
|
+
});
|
|
662
|
+
return attached;
|
|
663
|
+
}
|
|
664
|
+
function scanDetached(actual, desired, ops) {
|
|
665
|
+
let attachSetChanged = false;
|
|
666
|
+
for (const id of [...actual.keys()]) {
|
|
667
|
+
if (desired.has(id)) continue;
|
|
668
|
+
if (actual.get(id)?.attached) {
|
|
669
|
+
ops.push({
|
|
670
|
+
kind: "detach",
|
|
671
|
+
viewId: id
|
|
672
|
+
});
|
|
673
|
+
attachSetChanged = true;
|
|
674
|
+
}
|
|
675
|
+
actual.delete(id);
|
|
676
|
+
}
|
|
677
|
+
return attachSetChanged;
|
|
678
|
+
}
|
|
679
|
+
function classifyView(id, dv, actual, buckets) {
|
|
680
|
+
const a = actual.get(id);
|
|
681
|
+
if (!dv.placement.visible) {
|
|
682
|
+
if (a?.attached && a.visible) buckets.hides.push(id);
|
|
683
|
+
actual.set(id, {
|
|
684
|
+
attached: a?.attached ?? false,
|
|
685
|
+
visible: false,
|
|
686
|
+
bounds: a?.bounds,
|
|
687
|
+
extra: a?.extra
|
|
688
|
+
});
|
|
689
|
+
return false;
|
|
690
|
+
}
|
|
691
|
+
const bounds = visibleBounds(dv);
|
|
692
|
+
if (!a || !a.attached) {
|
|
693
|
+
buckets.shows.push(id);
|
|
694
|
+
actual.set(id, {
|
|
695
|
+
attached: true,
|
|
696
|
+
visible: true,
|
|
697
|
+
bounds,
|
|
698
|
+
extra: dv.extra
|
|
699
|
+
});
|
|
700
|
+
return true;
|
|
701
|
+
}
|
|
702
|
+
if (!a.visible) buckets.restores.push(id);
|
|
703
|
+
if (!sameBounds(a.bounds, bounds) || !sameExtra(a.extra, dv.extra)) buckets.updates.push(id);
|
|
704
|
+
actual.set(id, {
|
|
705
|
+
attached: true,
|
|
706
|
+
visible: true,
|
|
707
|
+
bounds,
|
|
708
|
+
extra: dv.extra
|
|
709
|
+
});
|
|
710
|
+
return false;
|
|
711
|
+
}
|
|
712
|
+
function emitOps(desired, actual, buckets, ops, attachSetChanged) {
|
|
713
|
+
for (const id of buckets.hides) ops.push({
|
|
714
|
+
kind: "setVisible",
|
|
715
|
+
viewId: id,
|
|
716
|
+
visible: false
|
|
717
|
+
});
|
|
718
|
+
buckets.shows.sort((a, b) => (desired.get(a)?.layer ?? 0) - (desired.get(b)?.layer ?? 0));
|
|
719
|
+
for (const id of buckets.shows) {
|
|
720
|
+
ops.push(setBoundsOp(id, desired.get(id)));
|
|
721
|
+
ops.push({
|
|
722
|
+
kind: "attach",
|
|
723
|
+
viewId: id
|
|
724
|
+
});
|
|
725
|
+
}
|
|
726
|
+
for (const id of buckets.restores) ops.push({
|
|
727
|
+
kind: "setVisible",
|
|
728
|
+
viewId: id,
|
|
729
|
+
visible: true
|
|
730
|
+
});
|
|
731
|
+
for (const id of buckets.updates) ops.push(setBoundsOp(id, desired.get(id)));
|
|
732
|
+
if (attachSetChanged) ops.push({
|
|
733
|
+
kind: "reorder",
|
|
734
|
+
order: computeOrder(actual, desired)
|
|
735
|
+
});
|
|
736
|
+
}
|
|
737
|
+
function reconcile(prev, snapshot) {
|
|
738
|
+
if (snapshot.generation < prev.generation) return {
|
|
739
|
+
state: { ...prev },
|
|
740
|
+
ops: []
|
|
741
|
+
};
|
|
742
|
+
if (snapshot.generation === prev.generation && snapshot.epoch <= prev.lastEpoch) return {
|
|
743
|
+
state: { ...prev },
|
|
744
|
+
ops: []
|
|
745
|
+
};
|
|
746
|
+
const resetGeneration = snapshot.generation > prev.generation;
|
|
747
|
+
const actual = /* @__PURE__ */ new Map();
|
|
748
|
+
if (!resetGeneration) for (const [id, a] of prev.actual) actual.set(id, { ...a });
|
|
749
|
+
const desired = /* @__PURE__ */ new Map();
|
|
750
|
+
for (const v of snapshot.views) desired.set(v.viewId, v);
|
|
751
|
+
const ops = [];
|
|
752
|
+
let attachSetChanged = scanDetached(actual, desired, ops);
|
|
753
|
+
const buckets = {
|
|
754
|
+
hides: [],
|
|
755
|
+
shows: [],
|
|
756
|
+
restores: [],
|
|
757
|
+
updates: []
|
|
758
|
+
};
|
|
759
|
+
for (const [id, dv] of desired) if (classifyView(id, dv, actual, buckets)) attachSetChanged = true;
|
|
760
|
+
emitOps(desired, actual, buckets, ops, attachSetChanged);
|
|
761
|
+
return {
|
|
762
|
+
state: {
|
|
763
|
+
generation: snapshot.generation,
|
|
764
|
+
lastEpoch: snapshot.epoch,
|
|
765
|
+
desired,
|
|
766
|
+
actual
|
|
767
|
+
},
|
|
768
|
+
ops
|
|
769
|
+
};
|
|
770
|
+
}
|
|
771
|
+
//#endregion
|
|
772
|
+
//#region src/layout/snapshot-reconcile.ts
|
|
773
|
+
function isFiniteNumber(v) {
|
|
774
|
+
return typeof v === "number" && Number.isFinite(v);
|
|
775
|
+
}
|
|
776
|
+
function isValidBounds(v) {
|
|
777
|
+
if (v === null || typeof v !== "object") return false;
|
|
778
|
+
const b = v;
|
|
779
|
+
return isFiniteNumber(b.x) && isFiniteNumber(b.y) && isFiniteNumber(b.width) && b.width >= 0 && isFiniteNumber(b.height) && b.height >= 0;
|
|
780
|
+
}
|
|
781
|
+
function isValidPlacement(v) {
|
|
782
|
+
if (v === null || typeof v !== "object") return false;
|
|
783
|
+
const p = v;
|
|
784
|
+
if (p.visible === true) return isValidBounds(p.bounds);
|
|
785
|
+
if (p.visible === false) return true;
|
|
786
|
+
return false;
|
|
787
|
+
}
|
|
788
|
+
function isNonNegInt(v) {
|
|
789
|
+
return typeof v === "number" && Number.isInteger(v) && v >= 0;
|
|
790
|
+
}
|
|
791
|
+
function readSlotToken(rawView) {
|
|
792
|
+
const extra = rawView.extra;
|
|
793
|
+
if (extra === null || typeof extra !== "object") return null;
|
|
794
|
+
const token = extra.slotToken;
|
|
795
|
+
return typeof token === "string" && token.length > 0 ? token : null;
|
|
796
|
+
}
|
|
797
|
+
/**
|
|
798
|
+
* Validate + authorize a raw renderer snapshot into a trusted CleanSnapshot.
|
|
799
|
+
*
|
|
800
|
+
* Returns null (REJECT — caller must NOT reconcile) when:
|
|
801
|
+
* - the payload is malformed (missing/!int generation/epoch, views not an array);
|
|
802
|
+
* - `views` is NON-EMPTY but every entry is dropped by authorization/validation
|
|
803
|
+
* — a fully-rejected snapshot must never be read as "the renderer wants
|
|
804
|
+
* everything detached" (that would tear down live views on a transient where
|
|
805
|
+
* tokens momentarily fail to resolve).
|
|
806
|
+
*
|
|
807
|
+
* Returns an EMPTY CleanSnapshot (not null) when `views` is genuinely empty — the
|
|
808
|
+
* renderer removed all its views, a legitimate signal the caller reconciles into
|
|
809
|
+
* detach ops.
|
|
810
|
+
*
|
|
811
|
+
* Each surviving view takes its `viewId`/`layer` from the AUTHORIZER, never from
|
|
812
|
+
* the renderer-reported fields (a valid token must not be splice-able onto a
|
|
813
|
+
* forged viewId to poison the reconciler key). Duplicate viewIds keep the first.
|
|
814
|
+
*/
|
|
815
|
+
function cleanOneView(rawView, authorize, seen) {
|
|
816
|
+
if (rawView === null || typeof rawView !== "object" || Array.isArray(rawView)) return null;
|
|
817
|
+
const rv = rawView;
|
|
818
|
+
const token = readSlotToken(rv);
|
|
819
|
+
if (token === null) return null;
|
|
820
|
+
const grant = authorize(token);
|
|
821
|
+
if (grant === null) return null;
|
|
822
|
+
if (!isValidPlacement(rv.placement)) return null;
|
|
823
|
+
if (seen.has(grant.viewId)) return null;
|
|
824
|
+
seen.add(grant.viewId);
|
|
825
|
+
return {
|
|
826
|
+
viewId: grant.viewId,
|
|
827
|
+
placement: rv.placement,
|
|
828
|
+
layer: grant.layer
|
|
829
|
+
};
|
|
830
|
+
}
|
|
831
|
+
function cleanSnapshot(raw, authorize) {
|
|
832
|
+
if (raw === null || typeof raw !== "object" || Array.isArray(raw)) return null;
|
|
833
|
+
const snap = raw;
|
|
834
|
+
if (!isNonNegInt(snap.generation) || !isNonNegInt(snap.epoch)) return null;
|
|
835
|
+
if (!Array.isArray(snap.views)) return null;
|
|
836
|
+
const rawViews = snap.views;
|
|
837
|
+
const views = [];
|
|
838
|
+
const seen = /* @__PURE__ */ new Set();
|
|
839
|
+
for (const rawView of rawViews) {
|
|
840
|
+
const cleaned = cleanOneView(rawView, authorize, seen);
|
|
841
|
+
if (cleaned) views.push(cleaned);
|
|
842
|
+
}
|
|
843
|
+
if (rawViews.length > 0 && views.length === 0) return null;
|
|
844
|
+
return {
|
|
845
|
+
generation: snap.generation,
|
|
846
|
+
epoch: snap.epoch,
|
|
847
|
+
views
|
|
848
|
+
};
|
|
849
|
+
}
|
|
850
|
+
/**
|
|
851
|
+
* Collapse reconcile ops onto a two-state per-view sink. Gathers the viewIds any
|
|
852
|
+
* op touched (reorder excluded — deck z-order is compositor zone-fixed), then for
|
|
853
|
+
* each reads the reconciled end-state from `state.actual`: attached+visible+bounds
|
|
854
|
+
* → apply({visible:true,bounds}); otherwise apply({visible:false}). Reading from
|
|
855
|
+
* `actual` (not the op itself) means a bare restore still carries its bounds.
|
|
856
|
+
*
|
|
857
|
+
* Each apply runs in its own try/catch: one throwing sink (e.g. a destroyed native
|
|
858
|
+
* view) must not abort the rest of the dispatch.
|
|
859
|
+
*/
|
|
860
|
+
function dispatchOps(ops, state, resolveApply) {
|
|
861
|
+
const touched = /* @__PURE__ */ new Set();
|
|
862
|
+
for (const op of ops) {
|
|
863
|
+
if (op.kind === "reorder") continue;
|
|
864
|
+
touched.add(op.viewId);
|
|
865
|
+
}
|
|
866
|
+
for (const viewId of touched) {
|
|
867
|
+
const apply = resolveApply(viewId);
|
|
868
|
+
if (!apply) continue;
|
|
869
|
+
const a = state.actual.get(viewId);
|
|
870
|
+
const placement = a && a.attached && a.visible && a.bounds ? {
|
|
871
|
+
visible: true,
|
|
872
|
+
bounds: a.bounds
|
|
873
|
+
} : { visible: false };
|
|
874
|
+
try {
|
|
875
|
+
apply(placement);
|
|
876
|
+
} catch (err) {
|
|
877
|
+
console.error(`[electron-deck] applyPlacement for view "${viewId}" threw:`, err);
|
|
878
|
+
}
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
//#endregion
|
|
882
|
+
export { serializeLayout as _, closePanelForUser as a, extractPanel as c, setActive as d, setConstraint as f, parseLayout as g, sanitizeFlexibleWeights as h, reconcile as i, insertPanel as l, splitPanel as m, dispatchOps as n, createLayoutModel as o, setSizes as p, createInitialState as r, closePanel as s, cleanSnapshot as t, movePanel as u, validateTree as v, createPanelRegistry as y };
|
|
618
883
|
|
|
619
|
-
//# sourceMappingURL=layout-
|
|
884
|
+
//# sourceMappingURL=layout-ByOiOdnc.js.map
|