@netless/appliance-plugin 1.1.42 → 1.1.43-beta.1

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 (112) hide show
  1. package/READMA.zh-CN.md +23 -1
  2. package/README.md +28 -1
  3. package/dist/appliance-plugin.js +1 -1
  4. package/dist/appliance-plugin.mjs +33 -30
  5. package/dist/{bridge-C8yT2GqS.js → bridge-CDqtVTPN.js} +1 -1
  6. package/dist/{bridge-DLGOhX8U.mjs → bridge-nmqVpnZ5.mjs} +1 -1
  7. package/dist/bridge.js +1 -1
  8. package/dist/bridge.mjs +1 -1
  9. package/dist/collector/collector.d.ts +50 -2
  10. package/dist/collector/types.d.ts +6 -0
  11. package/dist/component/svg/manager.d.ts +1 -0
  12. package/dist/component/svg/snapshot.d.ts +4 -1
  13. package/dist/component/textEditor/manager.d.ts +3 -0
  14. package/dist/core/backGroundThread/index.d.ts +6 -1
  15. package/dist/core/cameraTask.d.ts +45 -0
  16. package/dist/core/const.d.ts +4 -0
  17. package/dist/core/enum.d.ts +7 -1
  18. package/dist/core/error.d.ts +1 -0
  19. package/dist/core/fontFace.d.ts +5 -3
  20. package/dist/core/mainEngine.d.ts +236 -31
  21. package/dist/core/mainThread/base.d.ts +23 -2
  22. package/dist/core/mainThread/canvas2DReadback.d.ts +27 -0
  23. package/dist/core/mainThread/index.d.ts +12 -1
  24. package/dist/core/mainThread/snapshotThread.d.ts +11 -2
  25. package/dist/core/mainThread/subLocalThread.d.ts +15 -6
  26. package/dist/core/mainThread/subServiceThread.d.ts +5 -3
  27. package/dist/core/msgEvent/base.d.ts +4 -1
  28. package/dist/core/msgEvent/baseForWorker.d.ts +1 -1
  29. package/dist/core/msgEvent/copyNode/forWorker.d.ts +1 -1
  30. package/dist/core/msgEvent/forWorker.d.ts +1 -1
  31. package/dist/core/msgEvent/index.d.ts +5 -3
  32. package/dist/core/msgEvent/rotateNode/forMain.d.ts +1 -0
  33. package/dist/core/msgEvent/rotateNode/forWorker.d.ts +1 -1
  34. package/dist/core/msgEvent/scaleNode/forMain.d.ts +1 -0
  35. package/dist/core/msgEvent/scaleNode/forWorker.d.ts +1 -1
  36. package/dist/core/msgEvent/setColor/forMain.d.ts +1 -0
  37. package/dist/core/msgEvent/setColor/forWorker.d.ts +1 -1
  38. package/dist/core/msgEvent/setFont/forWorker.d.ts +1 -1
  39. package/dist/core/msgEvent/setLock/forWorker.d.ts +1 -1
  40. package/dist/core/msgEvent/setPoint/forWorker.d.ts +1 -1
  41. package/dist/core/msgEvent/setShape/forWorker.d.ts +1 -1
  42. package/dist/core/msgEvent/setZIndex/forWorker.d.ts +1 -1
  43. package/dist/core/msgEvent/translateNode/forMain.d.ts +1 -0
  44. package/dist/core/msgEvent/translateNode/forWorker.d.ts +1 -1
  45. package/dist/core/renderRuntimeFallback.d.ts +2 -0
  46. package/dist/core/rendererBusinessTask.d.ts +30 -0
  47. package/dist/core/serviceRenderScheduler.d.ts +33 -0
  48. package/dist/core/tools/base.d.ts +1 -1
  49. package/dist/core/tools/bitmapEraserFastPath.d.ts +8 -0
  50. package/dist/core/tools/eraserFaces.d.ts +24 -9
  51. package/dist/core/tools/image.d.ts +1 -0
  52. package/dist/core/tools/pencilEraserBitMap.d.ts +66 -14
  53. package/dist/core/tools/text.d.ts +2 -1
  54. package/dist/core/types.d.ts +66 -1
  55. package/dist/core/utils/indexDB.d.ts +3 -3
  56. package/dist/core/vNodeManager.d.ts +7 -0
  57. package/dist/core/worker/base.d.ts +52 -7
  58. package/dist/core/worker/fullWorkerLocal.d.ts +10 -2
  59. package/dist/core/worker/fullWorkerService.d.ts +7 -3
  60. package/dist/core/worker/renderCapabilityProbe.d.ts +54 -0
  61. package/dist/core/worker/simpleWorker.d.ts +2 -2
  62. package/dist/core/worker/snapshotWork.d.ts +1 -0
  63. package/dist/core/worker/workerManager.d.ts +17 -4
  64. package/dist/displayer/floatBar/selectorGesture.d.ts +2 -0
  65. package/dist/fullWorker.js +138 -139
  66. package/dist/index-B44o9ggV.mjs +56070 -0
  67. package/dist/{index-D8p2ph99.mjs → index-BF310Wzc.mjs} +401 -263
  68. package/dist/index-BJOPyRJn.js +1 -0
  69. package/dist/index-BiqhUSZ0.js +570 -0
  70. package/dist/index-Cjaia8CY.mjs +4107 -0
  71. package/dist/index-Cu0f4kha.js +570 -0
  72. package/dist/index-DDd-30M7.js +1 -0
  73. package/dist/index-DdbAM7Xi.mjs +4106 -0
  74. package/dist/index-DhCFlEfW.mjs +56062 -0
  75. package/dist/index-mcBiJOLo.mjs +931 -0
  76. package/dist/index-o1TaWHww.js +1 -0
  77. package/dist/index-puxStU6w.js +1 -0
  78. package/dist/plugin/applianceMultiPlugin.d.ts +18 -3
  79. package/dist/plugin/applianceSinglePlugin.d.ts +18 -4
  80. package/dist/plugin/baseApplianceManager.d.ts +138 -12
  81. package/dist/plugin/baseViewContainerManager.d.ts +40 -3
  82. package/dist/plugin/bitmapEraserOptions.d.ts +7 -0
  83. package/dist/plugin/const.d.ts +4 -0
  84. package/dist/plugin/displayerView.d.ts +7 -7
  85. package/dist/plugin/initLogAggregator.d.ts +45 -0
  86. package/dist/plugin/multi/applianceMultiManager.d.ts +1 -0
  87. package/dist/plugin/multi/containerManager.d.ts +19 -1
  88. package/dist/plugin/pluginInstanceOwner.d.ts +1 -0
  89. package/dist/plugin/renderImageBitmapRetirement.d.ts +100 -0
  90. package/dist/plugin/renderRuntimeCache.d.ts +18 -0
  91. package/dist/plugin/renderSurface.d.ts +15 -0
  92. package/dist/plugin/renderingCompatibility.d.ts +21 -5
  93. package/dist/plugin/roomLifecycle.d.ts +12 -0
  94. package/dist/plugin/selectorApi.d.ts +8 -0
  95. package/dist/plugin/single/applianceSingleManager.d.ts +4 -0
  96. package/dist/plugin/types.d.ts +9 -16
  97. package/dist/plugin/utils.d.ts +8 -0
  98. package/dist/subWorker.js +136 -137
  99. package/dist/undo/index.d.ts +12 -3
  100. package/dist/undo/timing.d.ts +9 -4
  101. package/package.json +23 -8
  102. package/dist/index--wqREfHK.js +0 -570
  103. package/dist/index-B-tFucpi.mjs +0 -48995
  104. package/dist/index-BOx854fU.mjs +0 -3266
  105. package/dist/index-BpiBM5wZ.js +0 -1
  106. package/dist/index-ByjVgxJm.js +0 -1
  107. package/dist/index-CSVCH-SQ.mjs +0 -789
  108. package/dist/index-CfIWmlMn.js +0 -570
  109. package/dist/index-D6gXcNbF.js +0 -1
  110. package/dist/index-HAZlgByL.mjs +0 -48987
  111. package/dist/index-OZXjSPr1.js +0 -1
  112. package/dist/index-z7deO9Md.mjs +0 -3267
@@ -1,21 +1,24 @@
1
1
  import EventEmitter2 from "eventemitter2";
2
2
  import { EStrokeType, MemberState, AppliancePluginLike, ApplianceInitLoadingChangeInfo, ApplianceFontFaceLoadState, ApplianceFontFaceRenderState, ApplianceRefreshRenderState, CallbacksFun } from "./types";
3
3
  import { Collector, ViewId } from "../collector";
4
+ import type { BaseCollectorReducerAction, DiffOneData, ISerializableStorageData } from "../collector/types";
4
5
  import { RoomMemberManager } from "../members";
5
6
  import { TextEditorManager } from "../component/textEditor";
6
- import type { Camera, Displayer, DisplayerCallbacks, ISVGMarkmapInformation, ISVGUrlInformation, IconifyInformation, Logger, MarkmapId, Player, Rectangle, RequiredAppliancePluginOptions, Room, RoomMember, _ArrayTrue } from "./types";
7
+ import type { Camera, Displayer, DisplayerCallbacks, ISVGMarkmapInformation, ISVGUrlInformation, IconifyInformation, MarkmapId, Player, Rectangle, RequiredAppliancePluginOptions, Room, RoomMember, _ArrayTrue } from "./types";
7
8
  import { CursorManager } from "../cursors";
8
9
  import { ViewContainerManager } from "./baseViewContainerManager";
9
- import { MasterControlForWorker } from "../core/mainEngine";
10
- import { EToolsKey } from "../core/enum";
10
+ import { MasterControlForWorker, type ForceDoneReason, type ViewForceDoneAck } from "../core/mainEngine";
11
+ import { EToolsKey, type ECanvasContextType } from "../core/enum";
11
12
  import { BaseShapeOptions } from "../core/tools/base";
12
13
  import { ICameraOpt } from "../core/types";
13
14
  import { HotkeyManager } from "../hotkey";
14
15
  import { SyncLogger } from "./syncLogger";
15
- import { RenderMode, RenderingCompatibilityDecision } from "./renderingCompatibility";
16
+ import { RenderMode, RenderingCompatibilityDecision, RenderingCompatibilityReason } from "./renderingCompatibility";
17
+ import type { WorkerRenderCapabilities } from "../core/worker/renderCapabilityProbe";
16
18
  import { RenderCotrolImple } from "../core/renderCotrol";
17
19
  import { MiniMapManagerImpl } from "../component/miniMap/manager";
18
20
  import { PluginManager, Plugin } from "../core/plugin";
21
+ import { LoggerUtils } from "./utils";
19
22
  import { SelectorApiManager } from "./selectorApi";
20
23
  import { BackgroundImageLoadCoordinator } from "../component/backgroundImageLoadCoordinator";
21
24
  import type { ReloadBackgroundImageParams, ReloadBackgroundImageResult } from "../component/backgroundImageLoadCoordinator";
@@ -25,6 +28,13 @@ export interface BaseApplianceManagerProps {
25
28
  options: RequiredAppliancePluginOptions;
26
29
  callbacks?: CallbacksFun;
27
30
  }
31
+ type PendingServiceDeriveData = DiffOneData<BaseCollectorReducerAction | undefined>;
32
+ export type ForceDoneAck = {
33
+ status: "success" | "failed";
34
+ reason: ForceDoneReason;
35
+ views: ViewForceDoneAck[];
36
+ failureReasons: string[];
37
+ };
28
38
  /** 插件管理器 */
29
39
  export declare abstract class BaseApplianceManager {
30
40
  readonly backgroundImageLoadCoordinator: BackgroundImageLoadCoordinator;
@@ -33,15 +43,30 @@ export declare abstract class BaseApplianceManager {
33
43
  private pendingSceneChecks;
34
44
  private pendingSceneChanges;
35
45
  private pendingClears;
46
+ private pendingViewInitStates;
47
+ private readonly renderRuntimeCacheKey;
48
+ private readonly renderRuntimeBuildMarker;
49
+ private renderRuntimeActivationPromise?;
50
+ /** Mounted Views initialize in arrival order so Init/ServiceSync postMessages do not pile up. */
51
+ private pendingViewInitQueue;
36
52
  private clearQueueByView;
37
53
  private viewOperationQueueByView;
54
+ private forceDoneQueue;
55
+ private forceDoneQueueByView;
56
+ private localMutationFenceCount;
57
+ private localMutationFenceByView;
58
+ private roomLifecycleTerminal;
59
+ private destroyPromise?;
60
+ private isDestroying;
61
+ private isDestroyed;
62
+ private orphanRepairTimer?;
38
63
  private lifecycleGeneration;
39
64
  private viewLifecycleGeneration;
40
65
  static InternalMsgEmitter: EventEmitter2;
41
66
  static PublicMsgEmitter: EventEmitter2;
42
67
  readonly version: string;
43
68
  plugin?: AppliancePluginLike;
44
- readonly logger: Logger;
69
+ readonly logger: LoggerUtils;
45
70
  readonly syncLogger: SyncLogger;
46
71
  readonly room?: Room;
47
72
  readonly play?: Player;
@@ -58,7 +83,8 @@ export declare abstract class BaseApplianceManager {
58
83
  effectResolve?: (value: boolean) => void;
59
84
  readonly hotkeyManager: HotkeyManager;
60
85
  readonly pluginOptions: RequiredAppliancePluginOptions;
61
- readonly renderMode: RenderMode;
86
+ renderMode: RenderMode;
87
+ private renderRuntimeDecisionLocked;
62
88
  readonly renderingCompatibilityDecision: RenderingCompatibilityDecision;
63
89
  readonly roomMember: RoomMemberManager;
64
90
  readonly cursor: CursorManager;
@@ -87,6 +113,15 @@ export declare abstract class BaseApplianceManager {
87
113
  notifyMainViewMounted(): void;
88
114
  isMainViewMounted(): boolean;
89
115
  waitForMainViewMounted(timeoutMs?: number): Promise<"ready" | "cancelled" | "timeout">;
116
+ isRenderRuntimeRecoveryAllowed(): boolean;
117
+ /**
118
+ * Serialize View mount-to-service-ready work and whole-runtime recovery in
119
+ * actual admission order. A recovery task owns this slot through all of its
120
+ * candidate attempts; nested work must execute directly to avoid self-wait.
121
+ */
122
+ private appendPendingViewInitTask;
123
+ queuePendingRuntimeReset<T>(task: () => Promise<T>): Promise<T>;
124
+ queuePendingViewInit(viewId: string, task: () => Promise<void>, generation?: number): Promise<void>;
90
125
  emitFontFaceLoadState(info: ApplianceFontFaceLoadState): void;
91
126
  emitFontFaceRenderState(info: ApplianceFontFaceRenderState): void;
92
127
  hasPolyfillMethod(methodName: "requestIdleCallback" | "cancelIdleCallback"): boolean;
@@ -126,7 +161,55 @@ export declare abstract class BaseApplianceManager {
126
161
  get hasOffscreenCanvas(): boolean;
127
162
  get isUseOffscreenTransfer(): boolean;
128
163
  isServiceSyncReady(viewId: string): boolean;
129
- applyWorkerRenderProbe(success: boolean): void;
164
+ onViewServiceReady(viewId: string): void;
165
+ lockRenderRuntimeDecision(): void;
166
+ isRenderRuntimeDecisionLocked(): boolean;
167
+ ensureRenderRuntimeReady(): Promise<void>;
168
+ getRenderContextTypeForView(viewId: string): ECanvasContextType;
169
+ requiresCanvas2DCompanionRenderProbe(): boolean;
170
+ protected restoreCachedRenderRuntimeDecision(): Promise<void>;
171
+ persistRenderRuntimeDecision(): Promise<void>;
172
+ invalidateRenderRuntimeDecision(): Promise<void>;
173
+ private ensurePendingViewInitState;
174
+ armPendingViewInit(viewId: string): void;
175
+ bindPendingViewInit(viewId: string, generation: number): void;
176
+ private nextInitPaddingSequence;
177
+ private getSceneInitPaddingState;
178
+ private appendInitPaddingJournal;
179
+ queuePendingInitScenePath(viewId: string, scenePath: string): void;
180
+ queuePendingInitServicePull(viewId: string, scenePath: string): void;
181
+ queuePendingInitCamera(viewId: string, cameraOpt: ICameraOpt, scenePath?: string): void;
182
+ queuePendingServiceDerive(viewId: string, key: string, data: PendingServiceDeriveData): void;
183
+ queuePendingInitClear(viewId: string, scenePath?: string): void;
184
+ getPendingInitTargetScenePath(viewId: string): string | undefined;
185
+ getPendingInitCameraForScene(viewId: string, scenePath: string): ICameraOpt | undefined;
186
+ markPendingInitServiceApplied(viewId: string, scenePath: string, snapshot: ISerializableStorageData | undefined, revision?: number): void;
187
+ resetPendingInitRendererBaseline(viewId: string): void;
188
+ getPendingInitServiceBaseline(viewId: string, scenePath: string): ISerializableStorageData;
189
+ getPendingInitReconcileRevision(viewId: string, scenePath: string): {
190
+ anchorRevision: number;
191
+ cameraRevision: number;
192
+ forceFullRevision: number;
193
+ };
194
+ getPendingInitLastApplied(viewId: string, scenePath: string): {
195
+ revision?: number;
196
+ storage?: ISerializableStorageData;
197
+ };
198
+ hasPendingInitAppliedSnapshot(viewId: string, scenePath: string): boolean;
199
+ isPendingInitForceFullRefresh(viewId: string, scenePath: string): boolean;
200
+ hasPendingInitServiceChanges(viewId: string, scenePath: string): boolean;
201
+ clearPendingViewInitState(viewId: string): void;
202
+ getViewLifecycleGeneration(viewId: string): number;
203
+ isPendingViewInitCurrent(viewId: string, generation: number): boolean;
204
+ invalidatePendingViewInit(viewId: string): number;
205
+ /**
206
+ * Cancel queued and in-flight pending init for every known View. A runtime
207
+ * reset is broader than one View lifecycle: even a queued task whose Worker
208
+ * has not been created yet must not run across the reset boundary.
209
+ */
210
+ invalidateAllPendingViewInit(): number;
211
+ applyWorkerRenderProbe(capabilities: WorkerRenderCapabilities): void;
212
+ applyRuntimeRenderingDecision(renderMode: RenderMode, contextType: ECanvasContextType, reason: RenderingCompatibilityReason, issue: string): void;
130
213
  logFinalRenderDecision(): void;
131
214
  /** 是否使用简单模式, 简单模式则无需开启 miniMap 和 plugin */
132
215
  get isUseSimple(): boolean;
@@ -135,22 +218,60 @@ export declare abstract class BaseApplianceManager {
135
218
  bindPlugin(plugin: AppliancePluginLike): void;
136
219
  /** 激活 plugin */
137
220
  abstract activePlugin(): void;
221
+ /**
222
+ * Apply one remote storage removal to the matching local transaction only.
223
+ * A full View/Scene removal passes no storage key and clears local rendering.
224
+ */
225
+ protected handleRemoteStorageRemoval(viewId: string, storageKey?: string, options?: {
226
+ abortAllContinuousMethods?: boolean;
227
+ cancelTicker?: boolean;
228
+ clearView?: boolean;
229
+ }): void;
138
230
  /** 初始化 */
139
231
  abstract init(): void;
140
232
  /** 激活worker */
141
233
  abstract activeWorker(): Promise<void>;
142
- /** 销毁 */
143
- destroy(): void;
234
+ private canForceDoneLocalWorks;
235
+ /**
236
+ * Shared lifecycle/runtime gate for immediate and queued local mutations.
237
+ * Entry-specific per-View busy and serialization checks stay in the caller.
238
+ */
239
+ private isLocalMutationRuntimeAvailable;
240
+ /**
241
+ * Synchronously admits new persistent content mutations for a View.
242
+ *
243
+ * This is an admission check only: it never finalizes an active operation,
244
+ * waits for a worker/Undo ACK, or changes Room member state. Callers that
245
+ * mutate storage must pass their target viewId so a View-scoped fence cannot
246
+ * be bypassed. MemberState/tool selection uses the Room API path separately.
247
+ */
248
+ canAcceptLocalMutation(viewId?: string): boolean;
249
+ /** A disconnected Room is one-way; a later join creates a new Manager. */
250
+ markRoomLifecycleTerminal(): void;
251
+ private canQueueViewLifecycleOperation;
252
+ acquireLocalMutationFence(targetViewIds?: readonly string[]): () => void;
253
+ /**
254
+ * 将当前可持久化的本地操作统一收口为 Done,并等待 Render/Storage/Undo 屏障。
255
+ * lifecycle 调用方必须在原 setWritable(false)/disconnect/destroy 之前 await。
256
+ */
257
+ forceDoneLocalWorks(reason: ForceDoneReason, targetViewIds?: readonly string[]): Promise<ForceDoneAck>;
258
+ private waitForForceDoneOrInvalidation;
259
+ private logLifecycleError;
260
+ /** 销毁;默认保留 storage,仅在连接且可写时先统一 force-Done。 */
261
+ destroy(options?: {
262
+ preserveStorage?: boolean;
263
+ }): Promise<void>;
264
+ private destroyImmediately;
144
265
  /** 清空当前获焦路径下的所有内容 */
145
- cleanCurrentScene(isForceEnd?: boolean): Promise<void>;
266
+ cleanCurrentScene(isForceEnd?: boolean): Promise<boolean>;
146
267
  isClearBusy(viewId: string): boolean;
147
268
  deferClearCamera(viewId: string, cameraOpt: ICameraOpt): void;
148
269
  private enqueueViewOperation;
149
- setWritable(isWritable: boolean): Promise<void>;
270
+ setWritable(isWritable: boolean): Promise<ForceDoneAck | undefined>;
150
271
  /** 监听读写状态变更 */
151
272
  onWritableChange(isWritable: boolean): void;
152
273
  /** 监听路径变化。每个 view 只保留最新目标页,避免快速切页渲染中间页面。 */
153
- onSceneChange: (scenePath: string, viewId: string) => Promise<void>;
274
+ onSceneChange: (requestedScenePath: string | undefined, viewId: string) => Promise<void>;
154
275
  private consumePendingSceneChanges;
155
276
  isSceneBusy(viewId: string): boolean;
156
277
  deferSceneCamera(viewId: string, cameraOpt: ICameraOpt): void;
@@ -164,6 +285,10 @@ export declare abstract class BaseApplianceManager {
164
285
  private schedulePendingSceneChecks;
165
286
  /** 监听房间成员变化 */
166
287
  onRoomMembersChange: (roomMembers: readonly RoomMember[]) => void;
288
+ private scheduleOrphanRepair;
289
+ private captureOrphanRepairMembers;
290
+ private isCurrentOrphanRepairMembers;
291
+ private repairOrphanStorage;
167
292
  /** 监听房间教具变更 */
168
293
  onMemberChange: import("lodash").DebouncedFunc<(memberState: MemberState) => void>;
169
294
  requestToolChange(modifyState: Partial<MemberState>): void;
@@ -218,3 +343,4 @@ export declare abstract class BaseApplianceManager {
218
343
  stopDraw(viewId: string): Promise<void>;
219
344
  setViewLocalScenePathChange(viewId: string, scenePath: string): Promise<void>;
220
345
  }
346
+ export {};
@@ -8,6 +8,7 @@ import { ShowFloatBarMsgValue } from "../displayer/types";
8
8
  import { UndoRedoMethod } from "../undo";
9
9
  import type { ExpectedAcks } from "../undo/timing";
10
10
  import { BaseViewDisplayer } from "./displayerView";
11
+ import { type RenderImageBitmapMemorySnapshot } from "./renderImageBitmapRetirement";
11
12
  export interface ViewInfo {
12
13
  id: string;
13
14
  focusScenePath: string;
@@ -27,7 +28,12 @@ export declare abstract class ViewContainerManager {
27
28
  abstract focuedViewId?: string;
28
29
  abstract focuedView?: ViewInfo;
29
30
  mainView?: ViewInfo;
31
+ protected mainViewOrigin?: ViewInfo;
32
+ protected readonly appViewOrigins: Map<string, ViewInfo>;
30
33
  appViews: Map<string, ViewInfo>;
34
+ private readonly renderImageBitmapRetirement;
35
+ private readonly renderImageBitmapRecoveryViews;
36
+ private renderImageBitmapPixelDiagnosticCanvas?;
31
37
  constructor(props: BaseSubWorkModuleProps);
32
38
  get worker(): import("../core/mainEngine").MasterControlForWorker;
33
39
  abstract getViewInitData(viewId: string): ViewWorkerOptions | undefined;
@@ -49,6 +55,7 @@ export declare abstract class ViewContainerManager {
49
55
  onFinalizeRequested: (id: number, viewId: string, workIds: string[], scenePath?: string) => void;
50
56
  onReopenStorageAck: (id: number, viewId: string, workIds: string[], scenePath?: string) => void;
51
57
  onCancelUndoTicker: (id: number, viewId: string, scenePath?: string) => void;
58
+ cancelViewUndoTicker(viewId: string): void;
52
59
  undo(): number;
53
60
  redo(): number;
54
61
  protected validator(target: ViewInfo, key: string, value: any): void;
@@ -57,14 +64,17 @@ export declare abstract class ViewContainerManager {
57
64
  createMianView(originMainView: ViewInfo): void;
58
65
  createAppView(originAppView: ViewInfo): void;
59
66
  isAppView(viewId: string): boolean;
67
+ getPreferredFocusedViewId(): string;
60
68
  getView(viewId: string): ViewInfo | undefined;
61
69
  private resolveView;
62
70
  private getViewElement;
63
71
  getFloatbarContainer(viewId?: string): HTMLElement | undefined;
64
72
  getViewOffsetToContainer(container: HTMLElement, viewId?: string): SelectorViewOffset | undefined;
65
73
  getCurScenePath(viewId: string): string | undefined;
74
+ getAuthoritativeScenePath(viewId: string): string | undefined;
66
75
  getAllViews(): (ViewInfo | undefined)[];
67
76
  setViewScenePath(viewId: string, scenePath: string): void;
77
+ setViewScenePathBeforeRenderInit(viewId: string, scenePath: string): boolean;
68
78
  setViewData(viewId: string, viewData: View): void;
69
79
  setFocuedViewId(viewId: string): void;
70
80
  setViewFocusScenePath(viewId: string, scenePath: string): void;
@@ -75,8 +85,15 @@ export declare abstract class ViewContainerManager {
75
85
  transformToOriginPoint(p: [number, number], viewId: string): [number, number];
76
86
  /** 页面坐标转换成view中心点坐标 */
77
87
  transformToScenePoint(p: [number, number], viewId: string): [number, number];
88
+ private inspectRenderImageBitmapPixels;
78
89
  /** 绘制view */
79
90
  render(renderData: IMainMessageRenderData[]): void;
91
+ /** 在一次 paint opportunity 之后释放已转移到主线程的渲染 Bitmap。 */
92
+ retireRenderImageBitmap(viewId: string, imageBitmap?: ImageBitmap): void;
93
+ /** View runtime 销毁时画布也会被丢弃,可以立即释放该 View 的 Bitmap。 */
94
+ disposeViewRenderImageBitmaps(viewId: string): void;
95
+ /** worker-image-bitmap 资源所有权诊断;estimatedBytes 不等同于实际 GPU 显存。 */
96
+ getRenderImageBitmapMemoryState(): RenderImageBitmapMemorySnapshot;
80
97
  /** 是否绘制浮动选框 */
81
98
  showFloatBar(viewId: string, isShow: boolean, opt?: Partial<ShowFloatBarMsgValue>): void;
82
99
  /** 激活文字编辑器 */
@@ -123,24 +140,40 @@ export declare abstract class BaseViewDisplayerManager {
123
140
  protected currentDrawingPointerId?: number;
124
141
  private pointerDrawingSession;
125
142
  private currentPointerDrawingSession?;
143
+ /** The single Done transition owned by the current pointer/touch gesture. */
144
+ private pointerDonePromise?;
126
145
  protected isTouchDrawing: boolean;
127
146
  protected cursorMouseMove: (e: MouseEvent) => void;
128
147
  protected cursorMouseMoveDebounced: DebouncedFunc<(e: MouseEvent) => void>;
129
148
  protected cursorMouseMoveThrottled: DebouncedFuncLeading<(e: MouseEvent) => void>;
130
149
  protected cursorMouseMoveFun: (e: MouseEvent) => void;
131
150
  private cursorEventElement?;
151
+ private eventTargetTouchAction?;
132
152
  private appliedCursorClassNames;
153
+ private pendingDpr?;
154
+ private dprMediaQuery?;
155
+ private dprMediaQueryListener?;
156
+ private pointLimitStopPending;
157
+ /** DOM 输入层计数,避免 localEventQueue 尚未消费时漏过点数上限。 */
158
+ private localBitmapEraserPointCount;
133
159
  private consumeClickerEvent;
134
160
  private _transferControlToOffscreenCanvas?;
135
161
  get moveDelayTime(): number;
136
162
  constructor(control: ApplianceManagerLike, internalMsgEmitter: EventEmitter2, viewId: string);
137
163
  protected cursorMouseLeave: () => void;
138
164
  abstract setCanvassStyle(): void;
165
+ protected requestDprUpdate(dpr: number): void;
166
+ commitDprUpdate(dpr: number): void;
167
+ cancelDprUpdate(): void;
168
+ protected resizeCanvasBackingStore(): void;
169
+ private observeDpr;
170
+ private stopObservingDpr;
139
171
  setTransferControlToOffscreenCanvas(canvas: {
140
172
  bgCanvas: HTMLCanvasElement;
141
173
  serviceCanvas: HTMLCanvasElement;
142
174
  localCanvas: HTMLCanvasElement;
143
175
  }): void;
176
+ resetRenderSurface(): Promise<void>;
144
177
  get transferControlToOffscreenCanvas(): {
145
178
  bgCanvas: OffscreenCanvas;
146
179
  serviceCanvas: OffscreenCanvas;
@@ -158,6 +191,7 @@ export declare abstract class BaseViewDisplayerManager {
158
191
  setActive(bol: boolean): void;
159
192
  focusElement(): void;
160
193
  stopEventHandler(): Promise<void>;
194
+ private finishPointerDone;
161
195
  protected getTranslate(element: any): any[];
162
196
  protected getContainerOffset(eventTraget: HTMLDivElement, offset: {
163
197
  x: number;
@@ -179,17 +213,21 @@ export declare abstract class BaseViewDisplayerManager {
179
213
  protected pointerup: (e: PointerEvent) => void;
180
214
  protected pointercancel: (e: PointerEvent) => void;
181
215
  protected clearTouchDocumentEvents(): void;
182
- protected cancelTouchDrawing(): void;
216
+ protected cancelTouchDrawing(reason?: string, setUnwritable?: boolean): void;
183
217
  protected touchstart: (e: TouchEvent) => void;
184
218
  protected touchmove: (e: TouchEvent) => void;
185
219
  protected touchend: (e: TouchEvent) => void;
186
220
  protected touchcancel: () => void;
221
+ private suppressNativeTouchGestures;
222
+ private restoreNativeTouchGestures;
187
223
  protected bindDisplayerEvent(div: HTMLDivElement): void;
188
224
  protected removeDisplayerEvent(div: HTMLDivElement): void;
189
225
  get isBezier(): boolean;
190
226
  get maxDrawCount(): number;
191
227
  /** 检查是否超过最大绘制数量 */
192
- checkConsumeCount(): boolean;
228
+ private isBitmapEraserTool;
229
+ private getFullLayerBitmapEraserMaxInputPoints;
230
+ checkConsumeCount(hasPoint?: boolean): boolean;
193
231
  }
194
232
  /** appView容器管理器抽象 */
195
233
  export declare abstract class AppViewDisplayerManager extends BaseViewDisplayerManager {
@@ -206,5 +244,4 @@ export declare abstract class MainViewDisplayerManager extends BaseViewDisplayer
206
244
  constructor(control: ApplianceManagerLike, internalMsgEmitter: EventEmitter2);
207
245
  get viewId(): string;
208
246
  updateSize(): void;
209
- destroy(): void;
210
247
  }
@@ -0,0 +1,7 @@
1
+ /** FullLayer 快路径单次事务最多接收的输入点数默认值。 */
2
+ export declare const DefaultFullLayerDoingMaskMaxInputPoints = 500;
3
+ /**
4
+ * 归一化客户可配置的 FullLayer Bitmap Eraser 点数上限。
5
+ * 该值只约束单个本地事务的逻辑 Point2d 数量,不代表像素或数组长度。
6
+ */
7
+ export declare function normalizeFullLayerDoingMaskMaxInputPoints(value: unknown): number;
@@ -3,6 +3,10 @@ export { normalizeCursorOptions } from "../cursors/options";
3
3
  export type { NormalizedCursorOptions } from "../cursors/options";
4
4
  export declare const pkg_version: string;
5
5
  export declare const pkg_name: string;
6
+ export declare const renderRuntimeBuildMarker: string;
7
+ export declare const DefaultUndoAckTimeout = 5000;
8
+ export declare const ClearUndoStackEndTimeout = 10000;
9
+ export declare const BitmapEraserCommitTimeout = 10000;
6
10
  export declare const DefaultAppliancePluginExtrasOptions: Required<Omit<RequiredExtrasOptions, "canvasOpt">>;
7
11
  type DefaultCursorAppearance = CursorAppearance & Required<Pick<CursorVisual, "images" | "size" | "offset">> & {
8
12
  local: NonNullable<CursorAppearance["local"]> & {
@@ -3,19 +3,14 @@ import { EmitEventType, ApplianceViewManagerLike } from "./types";
3
3
  import { TextEditorInfo } from "../component/textEditor";
4
4
  import { ShowFloatBarMsgValue } from "../displayer/types";
5
5
  import type { SelectorStyleOverrides } from "./types";
6
+ import { type RenderSurfaceRefs } from "./renderSurface";
6
7
  export interface BaseDisplayerProps {
7
8
  viewId: string;
8
9
  mananger: ApplianceViewManagerLike;
9
- refs: {
10
+ refs: RenderSurfaceRefs & {
10
11
  snapshotContainerRef?: React.RefObject<HTMLDivElement>;
11
12
  backgroundContainerRef?: React.RefObject<HTMLDivElement>;
12
13
  backgroundSnapshotContainerRef?: React.RefObject<HTMLDivElement>;
13
- canvasContainerRef: React.RefObject<HTMLDivElement>;
14
- subLocalCanvasContainerRef?: React.RefObject<HTMLDivElement>;
15
- canvasServiceFloatRef: React.RefObject<HTMLCanvasElement>;
16
- canvasFloatRef: React.RefObject<HTMLCanvasElement>;
17
- canvasBgRef: React.RefObject<HTMLCanvasElement>;
18
- canvasTopRef?: React.RefObject<HTMLCanvasElement>;
19
14
  floatBarRef: React.RefObject<HTMLDivElement>;
20
15
  customFloatbarContainerRef: React.RefObject<HTMLDivElement>;
21
16
  };
@@ -32,6 +27,7 @@ export interface BaseDisplayerState {
32
27
  activeTextId?: string;
33
28
  activeMiniMapViewId?: string;
34
29
  activeTextEditor?: boolean;
30
+ renderSurfaceGeneration: number;
35
31
  }
36
32
  export declare const DisplayerContext: React.Context<Pick<BaseDisplayerState, "scale" | "dpr" | "angle" | "floatBarData" | "operationType" | "activeTextEditor" | "activeTextId"> & {
37
33
  viewId: string;
@@ -47,10 +43,14 @@ export declare class BaseViewDisplayer extends React.Component<BaseDisplayerProp
47
43
  showTextFloatBar: boolean;
48
44
  canSelectorSwitch: boolean;
49
45
  rightBoundBreak: boolean;
46
+ private isUnmounted;
47
+ private readonly renderSurfaceResetWaiters;
50
48
  constructor(props: BaseDisplayerProps);
51
49
  private get editors();
52
50
  componentDidMount(): void;
53
51
  componentWillUnmount(): void;
52
+ setDpr(dpr: number): void;
53
+ resetRenderSurface(timeoutMs?: number): Promise<void>;
54
54
  setActiveMiniMap(viewId?: string): void;
55
55
  showFloatBarBtn(bol: boolean): void;
56
56
  showFloatBar(show: boolean, value?: Partial<ShowFloatBarMsgValue>): void;
@@ -0,0 +1,45 @@
1
+ export declare const InitProgressLogDelayMs = 500;
2
+ export type InitLogCategory = "render-init" | "init-padding" | "init-reconcile";
3
+ export type InitLogDetails = Record<string, string | number | boolean | null | undefined>;
4
+ export type InitLogProgressEvent = {
5
+ category: InitLogCategory;
6
+ viewId: string;
7
+ stage: string;
8
+ generation?: string | number;
9
+ lifecycleGeneration?: number;
10
+ details?: InitLogDetails;
11
+ restartView?: boolean;
12
+ };
13
+ export type InitLogCompletion = {
14
+ viewId: string;
15
+ generation?: string | number;
16
+ details?: InitLogDetails;
17
+ };
18
+ type TimerHandle = ReturnType<typeof setTimeout>;
19
+ type InitLogAggregatorOptions = {
20
+ delayMs?: number;
21
+ schedule?: (callback: () => void, delayMs: number) => TimerHandle;
22
+ cancel?: (timer: TimerHandle) => void;
23
+ };
24
+ export declare function formatInitLogEvent(event: InitLogProgressEvent): string;
25
+ export declare function formatInitLogCompletion(completion: InitLogCompletion): string;
26
+ export declare class InitLogAggregator {
27
+ private readonly emit;
28
+ private readonly delayMs;
29
+ private readonly schedule;
30
+ private readonly cancel;
31
+ private readonly states;
32
+ private destroyed;
33
+ constructor(emit: (message: string) => void, options?: InitLogAggregatorOptions);
34
+ record(event: InitLogProgressEvent): void;
35
+ completeView(completion: InitLogCompletion): void;
36
+ cancelView(viewId: string): void;
37
+ destroy(): void;
38
+ private updateState;
39
+ private scheduleState;
40
+ private clearState;
41
+ private hasViewLifecycle;
42
+ private formatSummary;
43
+ private emitSummary;
44
+ }
45
+ export {};
@@ -6,6 +6,7 @@ export declare class ApplianceMultiManager extends BaseApplianceManager {
6
6
  windowManager?: WindowManager;
7
7
  viewContainerManager: ViewContainerMultiManager;
8
8
  constructor(params: BaseApplianceManagerProps);
9
+ requiresCanvas2DCompanionRenderProbe(): boolean;
9
10
  init(): void;
10
11
  activePlugin(): void;
11
12
  activeWorker(): Promise<void>;
@@ -11,20 +11,38 @@ export declare class ViewContainerMultiManager extends ViewContainerManager {
11
11
  /** 针对windowmanager的focusedChange先于onAppViewMounted*/
12
12
  tmpFocusedViewId?: string;
13
13
  private checkScaleTimer?;
14
+ private windowManager?;
15
+ private mainViewLifecycleRevision;
16
+ private readonly appViewLifecycleRevisionById;
17
+ private readonly appScenePathRetryTimerById;
18
+ private bumpAppViewLifecycleRevision;
19
+ private isCurrentAppViewLifecycleRevision;
20
+ private cancelAppScenePathRetry;
21
+ private consumeAppScenePathWhenReady;
22
+ private readonly focusedChangeListener;
23
+ getPreferredFocusedViewId(): string;
24
+ getAuthoritativeScenePath(viewId: string): string | undefined;
25
+ private readonly mainViewScenePathChangeListener;
26
+ private readonly boxCloseListener;
27
+ private readonly appScenePathChangeListener;
28
+ private readonly appsChangeListener;
14
29
  private readonly mainViewHotkeyListener;
15
30
  private readonly appViewListeners;
16
31
  constructor(props: BaseSubWorkModuleProps);
32
+ private logMainViewCameraTrace;
17
33
  private getAppViewListeners;
18
34
  private removeMainViewListeners;
19
35
  private removeAppViewListeners;
20
36
  destroyAppView(viewId: string, justLocal?: boolean): void;
21
37
  destroy(): void;
38
+ private removeWindowManagerListeners;
22
39
  getViewInitData(viewId: string): ViewWorkerOptions | undefined;
23
40
  mountView(viewId: string): Promise<void>;
24
41
  listenerWindowManager(windowManager: WindowManager): void;
25
42
  private onMainViewRelease;
26
43
  private mainViewDestroy;
27
- onMainViewMounted: (bindMainView: View) => void;
44
+ onMainViewMounted: (bindMainView: View) => Promise<void>;
45
+ private mountMainView;
28
46
  private onMainViewSizeUpdated;
29
47
  private onMainViewCameraUpdated;
30
48
  private updateMainViewCamera;
@@ -0,0 +1 @@
1
+ export declare function createOwnedPluginInstanceProxy<T extends object, TManager extends object>(target: T, ownedManager: TManager | undefined, getCurrentManager: () => TManager | undefined): T;
@@ -0,0 +1,100 @@
1
+ export declare const RenderImageBitmapRetireTimeoutMs = 5000;
2
+ export declare const RenderImageBitmapMemoryPressureBytes: number;
3
+ export declare const RenderImageBitmapMemoryPressureCount = 128;
4
+ export declare const RenderImageBitmapMemoryPressureReportIntervalMs = 5000;
5
+ type TimerHandle = ReturnType<typeof setTimeout>;
6
+ export type RenderImageBitmapRetirementScheduler = {
7
+ requestFrame: (callback: FrameRequestCallback) => number;
8
+ cancelFrame: (handle: number) => void;
9
+ setTimer: (callback: () => void, timeoutMs: number) => TimerHandle;
10
+ clearTimer: (handle: TimerHandle) => void;
11
+ now: () => number;
12
+ };
13
+ export type RenderImageBitmapRetirementOptions = {
14
+ timeoutMs?: number;
15
+ memoryPressureBytes?: number;
16
+ memoryPressureCount?: number;
17
+ memoryPressureReportIntervalMs?: number;
18
+ scheduler?: Partial<RenderImageBitmapRetirementScheduler>;
19
+ onCloseError?: (viewId: string, error: unknown, snapshot: RenderImageBitmapMemorySnapshot) => void;
20
+ onScheduleError?: (stage: "request-frame" | "set-watchdog", error: unknown, snapshot: RenderImageBitmapMemorySnapshot) => void;
21
+ onTimeout?: (event: RenderImageBitmapTimeoutEvent) => void;
22
+ onMemoryPressure?: (snapshot: RenderImageBitmapMemorySnapshot) => void;
23
+ };
24
+ export type RenderImageBitmapMemoryViewSnapshot = Readonly<{
25
+ viewId: string;
26
+ activeCount: number;
27
+ estimatedBytes: number;
28
+ oldestAgeMs: number;
29
+ }>;
30
+ /**
31
+ * Tracks ImageBitmap ownership, not browser heap or exact GPU allocation.
32
+ * estimatedBytes uses width * height * 4 as a stable pressure signal.
33
+ */
34
+ export type RenderImageBitmapMemorySnapshot = Readonly<{
35
+ activeCount: number;
36
+ estimatedBytes: number;
37
+ peakActiveCount: number;
38
+ peakEstimatedBytes: number;
39
+ totalRetiredCount: number;
40
+ totalReleasedCount: number;
41
+ watchdogReleasedCount: number;
42
+ closeErrorCount: number;
43
+ oldestAgeMs: number;
44
+ activeViews: ReadonlyArray<RenderImageBitmapMemoryViewSnapshot>;
45
+ destroyed: boolean;
46
+ }>;
47
+ export type RenderImageBitmapTimeoutEvent = Readonly<{
48
+ viewIds: ReadonlySet<string>;
49
+ releasedCount: number;
50
+ releasedEstimatedBytes: number;
51
+ oldestAgeMs: number;
52
+ snapshot: RenderImageBitmapMemorySnapshot;
53
+ }>;
54
+ export declare function getRenderImageBitmapDestroyLogLevel(beforeDestroy: RenderImageBitmapMemorySnapshot, afterDestroy: RenderImageBitmapMemorySnapshot): "error" | "info" | undefined;
55
+ /**
56
+ * Keeps transferred render bitmaps alive across one browser paint opportunity.
57
+ * The first RAF promotes a bitmap to awaitingPaint; the second RAF releases it.
58
+ */
59
+ export declare class RenderImageBitmapRetirementQueue {
60
+ private pending;
61
+ private awaitingPaint;
62
+ private readonly entries;
63
+ private readonly timeoutMs;
64
+ private readonly memoryPressureBytes;
65
+ private readonly memoryPressureCount;
66
+ private readonly memoryPressureReportIntervalMs;
67
+ private readonly scheduler;
68
+ private readonly onCloseError?;
69
+ private readonly onScheduleError?;
70
+ private readonly onTimeout?;
71
+ private readonly onMemoryPressure?;
72
+ private activeEstimatedBytes;
73
+ private peakActiveCount;
74
+ private peakEstimatedBytes;
75
+ private totalRetiredCount;
76
+ private totalReleasedCount;
77
+ private watchdogReleasedCount;
78
+ private closeErrorCount;
79
+ private lastMemoryPressureReportAt;
80
+ private frameHandle?;
81
+ private watchdogHandle?;
82
+ private destroyed;
83
+ constructor(options?: RenderImageBitmapRetirementOptions);
84
+ retire(viewId: string, bitmap: ImageBitmap): void;
85
+ getMemorySnapshot(): RenderImageBitmapMemorySnapshot;
86
+ closeNow(viewId: string, bitmap: ImageBitmap): void;
87
+ releaseView(viewId: string): void;
88
+ destroy(): RenderImageBitmapMemorySnapshot;
89
+ private ensureFrame;
90
+ private readonly onFrame;
91
+ private ensureWatchdog;
92
+ private readonly onWatchdog;
93
+ private releaseEntry;
94
+ private closeBitmap;
95
+ private estimateBitmapBytes;
96
+ private reportMemoryPressure;
97
+ private stopSchedulersWhenEmpty;
98
+ private cancelSchedulers;
99
+ }
100
+ export {};
@@ -0,0 +1,18 @@
1
+ import { type CompactRenderModel } from "./renderingCompatibility";
2
+ export declare const RenderModeCacheDatabaseName = "__APPLIANCE_PLUGIN_RENDER_MODE_DB";
3
+ export declare const RenderModeCacheStoreName = "renderModes";
4
+ export type CachedRenderRuntimeReadResult = {
5
+ renderModel?: CompactRenderModel;
6
+ readFailed?: boolean;
7
+ reason?: string;
8
+ };
9
+ type IDBFactoryLike = Pick<IDBFactory, "open"> & Partial<Pick<IDBFactory, "deleteDatabase">>;
10
+ export type RenderRuntimeCacheDeadlineOptions = {
11
+ timeoutMs?: number;
12
+ };
13
+ export declare function createRenderRuntimeCacheKey(userAgent: string): string;
14
+ export declare function readCachedRenderRuntimeDecisionWithStatus(key: string, factory?: IDBFactoryLike | undefined, options?: RenderRuntimeCacheDeadlineOptions): Promise<CachedRenderRuntimeReadResult>;
15
+ export declare function readCachedRenderRuntimeDecision(key: string, factory?: IDBFactoryLike | undefined, options?: RenderRuntimeCacheDeadlineOptions): Promise<CompactRenderModel | undefined>;
16
+ export declare function writeCachedRenderRuntimeDecision(key: string, renderModel: CompactRenderModel, factory?: IDBFactoryLike | undefined, options?: RenderRuntimeCacheDeadlineOptions): Promise<boolean>;
17
+ export declare function deleteCachedRenderRuntimeDecision(key: string, factory?: IDBFactoryLike | undefined, options?: RenderRuntimeCacheDeadlineOptions): Promise<boolean>;
18
+ export {};