@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.
Files changed (42) hide show
  1. package/dist/client/index.d.ts +2 -0
  2. package/dist/client/index.d.ts.map +1 -1
  3. package/dist/client/index.js +92 -12
  4. package/dist/client/index.js.map +1 -1
  5. package/dist/client/layout-client.d.ts +35 -14
  6. package/dist/client/layout-client.d.ts.map +1 -1
  7. package/dist/client/placement-publisher.d.ts +14 -0
  8. package/dist/client/placement-publisher.d.ts.map +1 -0
  9. package/dist/dock-react/index.js +1 -1
  10. package/dist/{electron-deck-C9_Yu3fd.js → electron-deck-B9fun93z.js} +105 -78
  11. package/dist/electron-deck-B9fun93z.js.map +1 -0
  12. package/dist/host/index.js +1 -1
  13. package/dist/index.js +1 -1
  14. package/dist/internal/deck-app.d.ts +43 -11
  15. package/dist/internal/deck-app.d.ts.map +1 -1
  16. package/dist/internal/wire-transport.d.ts +17 -14
  17. package/dist/internal/wire-transport.d.ts.map +1 -1
  18. package/dist/layout/index.d.ts +4 -0
  19. package/dist/layout/index.d.ts.map +1 -1
  20. package/dist/layout/index.js +2 -2
  21. package/dist/layout/placement-reconcile.d.ts +50 -0
  22. package/dist/layout/placement-reconcile.d.ts.map +1 -0
  23. package/dist/layout/snapshot-reconcile.d.ts +28 -0
  24. package/dist/layout/snapshot-reconcile.d.ts.map +1 -0
  25. package/dist/{layout-B1t15b_q.js → layout-ByOiOdnc.js} +267 -2
  26. package/dist/layout-ByOiOdnc.js.map +1 -0
  27. package/dist/main/index.js +1 -1
  28. package/dist/main/view-handle.d.ts.map +1 -1
  29. package/dist/preload/index.cjs +4 -4
  30. package/dist/preload/index.cjs.map +1 -1
  31. package/dist/preload/index.d.ts +1 -1
  32. package/dist/preload/index.js +4 -4
  33. package/dist/preload/index.js.map +1 -1
  34. package/dist/{protocol-BJqo-vP2.js → protocol-B6TOT9AP.js} +2 -2
  35. package/dist/protocol-B6TOT9AP.js.map +1 -0
  36. package/dist/shared/protocol.d.ts +1 -1
  37. package/dist/{view-handle-CR-yWNfr.js → view-handle-DDhpBuW-.js} +2 -2
  38. package/dist/{view-handle-CR-yWNfr.js.map → view-handle-DDhpBuW-.js.map} +1 -1
  39. package/package.json +4 -4
  40. package/dist/electron-deck-C9_Yu3fd.js.map +0 -1
  41. package/dist/layout-B1t15b_q.js.map +0 -1
  42. 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:place` apply path looks the token up,
147
- * checks the sender is the authorized wc (anti-spoof), validates the placement,
148
- * then `apply`s it. `resend` re-pushes the slot-grant (layout-subscribe replay).
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:place`). The token is the credential:
378
- * look it up, verify the sender IS the wc the token was granted to (anti-spoof),
379
- * validate the placement, then apply. Any failure → DROP (silent).
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 handleSlotPlace;
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), re-push every grant
385
- * it owns so it can re-bind its DOM slots. A DIFFERENT wc's subscribe never
386
- * receives another wc's grants.
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` (window-close / shutdown hygiene). */
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":"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"}
1
+ {"version":3,"file":"deck-app.d.ts","sourceRoot":"","sources":["../../src/internal/deck-app.ts"],"names":[],"mappings":"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"}
@@ -83,11 +83,13 @@ export interface WireTransportDeps {
83
83
  */
84
84
  readonly declaredEvents: () => readonly string[];
85
85
  /**
86
- * OPTIONAL slot-token inbound: `__electron-deck:place` apply path. When
87
- * provided, `start()` registers the `Place` handler (same trust + main-frame
88
- * gate as invoke). On gate pass → `onPlace(senderId, slotToken, placement)`.
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 onPlace?: (senderId: number, slotToken: string, placement: unknown) => void;
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 Place / LayoutSubscribe handlers were registered
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 placeRegistered;
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 onPlaceCb;
112
+ private onSnapshotCb;
111
113
  private onLayoutSubscribeCb;
112
114
  constructor(deps: WireTransportDeps);
113
115
  start(): void;
114
116
  private tryRemoveHandler;
115
- private registerPlaceHandler;
116
- private unregisterPlaceHandler;
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(onPlace: (senderId: number, slotToken: string, placement: unknown) => void, onLayoutSubscribe: (senderId: number) => void): void;
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:place` inbound. Same gate as {@link handleInvoke}
148
- * (trust + main-frame). On any failure (malformed payload, untrusted sender,
149
- * sub-frame) → DROP silently (return undefined; never call `onPlace`).
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 handlePlace;
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":"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"}
1
+ {"version":3,"file":"wire-transport.d.ts","sourceRoot":"","sources":["../../src/internal/wire-transport.ts"],"names":[],"mappings":"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"}
@@ -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"}
@@ -1,2 +1,2 @@
1
- import { a as insertPanel, c as setConstraint, d as sanitizeFlexibleWeights, f as parseLayout, h as createPanelRegistry, i as extractPanel, l as setSizes, m as validateTree, n as createLayoutModel, o as movePanel, p as serializeLayout, r as closePanel, s as setActive, t as closePanelForUser, u as splitPanel } from "../layout-B1t15b_q.js";
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
- export { insertPanel as a, setConstraint as c, sanitizeFlexibleWeights as d, parseLayout as f, createPanelRegistry as h, extractPanel as i, setSizes as l, validateTree as m, createLayoutModel as n, movePanel as o, serializeLayout as p, closePanel as r, setActive as s, closePanelForUser as t, splitPanel as u };
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-B1t15b_q.js.map
884
+ //# sourceMappingURL=layout-ByOiOdnc.js.map