@lvce-editor/api 8.50.0 → 8.52.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -18,7 +18,7 @@ export { executeSourceControlAcceptInput, executeSourceControlAdd, executeSource
18
18
  export { createViewInstance, dispatchViewEvent, disposeViewInstance, executeViewProvider, getViewRegistrySnapshot, renderViewInstance, registerView, resetViewRegistry, saveViewInstanceState, } from './parts/ViewRegistry/ViewRegistry.ts';
19
19
  export { createOutputChannel, getOutputChannelRegistrySnapshot, resetOutputChannelRegistry } from './parts/OutputChannel/OutputChannel.ts';
20
20
  export { getStatusBarItemProviderRegistrySnapshot, registerStatusBarItemProvider, resetStatusBarItemProviderRegistry, } from './parts/StatusBar/StatusBar.ts';
21
- export type { RegisteredView, View, ViewAction, ViewCommand, ViewContext, ViewEvent, ViewKind, MenuEntry, ViewRegistrySnapshot, ViewRenderResult, ViewSelection, VirtualDomViewInstance, } from './parts/View/View.ts';
21
+ export type { RegisteredView, View, ViewAction, ViewCommand, ViewContext, ViewEvent, ViewKind, MenuEntry, ViewRegistrySnapshot, ViewRenderResult, ViewScrollPosition, ViewSelection, VirtualDomViewInstance, } from './parts/View/View.ts';
22
22
  export { handleExtensionManagementMessagePort } from './parts/HandleExtensionManagementMessagePort/HandleExtensionManagementMessagePort.ts';
23
23
  export { createNodeRpc, createRpc } from './parts/Rpc/Rpc.ts';
24
24
  export type { Command } from './parts/Command/Command.ts';
@@ -5,8 +5,9 @@ export interface CreateRpcOptions {
5
5
  readonly url: string;
6
6
  }
7
7
  export interface CreateNodeRpcOptions {
8
+ readonly id?: string;
8
9
  readonly name?: string;
9
- readonly path: string;
10
+ readonly path?: string;
10
11
  }
11
12
  export declare const createRpc: ({ commandMap, name, url }: CreateRpcOptions) => Promise<Rpc>;
12
- export declare const createNodeRpc: ({ name, path }: CreateNodeRpcOptions) => Promise<Rpc>;
13
+ export declare const createNodeRpc: (options: CreateNodeRpcOptions) => Promise<Rpc>;
@@ -17,14 +17,24 @@ const createMessagePortRpc = async (commandMap, send) => {
17
17
  export const createRpc = async ({ commandMap = {}, name = '', url }) => {
18
18
  return createMessagePortRpc(commandMap, (port) => sendMessagePortToWebWorker(port, name, url));
19
19
  };
20
- export const createNodeRpc = async ({ name = '', path }) => {
21
- const id = await ExtensionManagementWorker.invoke('Extensions.executeCommand', 'ExtensionNodeRpc.create', name, path);
20
+ const resolveNodeRpcOptions = async ({ id, name = '', path }) => {
21
+ if (id) {
22
+ return ExtensionManagementWorker.invoke('Extensions.getNodeRpcInfo', id);
23
+ }
24
+ if (path) {
25
+ return { name, path };
26
+ }
27
+ throw new TypeError('createNodeRpc requires an id or path');
28
+ };
29
+ export const createNodeRpc = async (options) => {
30
+ const { name, path } = await resolveNodeRpcOptions(options);
31
+ const rpcId = await ExtensionManagementWorker.invoke('Extensions.executeCommand', 'ExtensionNodeRpc.create', name, path);
22
32
  const invoke = (method, ...params) => {
23
- return ExtensionManagementWorker.invoke('Extensions.executeCommand', 'ExtensionNodeRpc.invoke', id, method, ...params);
33
+ return ExtensionManagementWorker.invoke('Extensions.executeCommand', 'ExtensionNodeRpc.invoke', rpcId, method, ...params);
24
34
  };
25
35
  return {
26
36
  async dispose() {
27
- await ExtensionManagementWorker.invoke('Extensions.executeCommand', 'ExtensionNodeRpc.dispose', id);
37
+ await ExtensionManagementWorker.invoke('Extensions.executeCommand', 'ExtensionNodeRpc.dispose', rpcId);
28
38
  },
29
39
  invoke,
30
40
  invokeAndTransfer: invoke,
@@ -31,6 +31,7 @@ export interface ViewSelection {
31
31
  readonly name: string;
32
32
  readonly start: number;
33
33
  }
34
+ export type ViewScrollPosition = readonly [selector: string, scrollTop: number];
34
35
  export interface DomEventListener {
35
36
  readonly capture?: boolean;
36
37
  readonly name: string | number;
@@ -48,6 +49,7 @@ export interface VirtualDomViewInstance {
48
49
  readonly render: () => readonly VirtualDomNode[] | Promise<readonly VirtualDomNode[]>;
49
50
  readonly renderActions?: () => readonly ViewAction[] | Promise<readonly ViewAction[]>;
50
51
  readonly renderFocus?: (oldContext: Readonly<Record<string, boolean>>, newContext: Readonly<Record<string, boolean>>) => string | Promise<string>;
52
+ readonly renderScrollPosition?: () => readonly [] | ViewScrollPosition | Promise<readonly [] | ViewScrollPosition>;
51
53
  readonly renderSelections?: () => readonly ViewSelection[] | Promise<readonly ViewSelection[]>;
52
54
  readonly renderTitle?: () => string | Promise<string>;
53
55
  readonly saveState?: () => unknown;
@@ -79,6 +81,7 @@ export interface ViewRegistrySnapshot {
79
81
  export interface ViewRenderResultDom {
80
82
  readonly dom: readonly VirtualDomNode[];
81
83
  readonly focusSelector?: string;
84
+ readonly scrollPosition?: ViewScrollPosition;
82
85
  readonly selections?: readonly ViewSelection[];
83
86
  readonly title?: string;
84
87
  readonly type: 'setDom';
@@ -86,6 +89,7 @@ export interface ViewRenderResultDom {
86
89
  export interface ViewRenderResultPatches {
87
90
  readonly focusSelector?: string;
88
91
  readonly patches: readonly unknown[];
92
+ readonly scrollPosition?: ViewScrollPosition;
89
93
  readonly selections?: readonly ViewSelection[];
90
94
  readonly title?: string;
91
95
  readonly type: 'setPatches';
@@ -262,6 +262,20 @@ const normalizeViewSelections = (selections) => {
262
262
  }
263
263
  return selections.map(normalizeViewSelection);
264
264
  };
265
+ const normalizeViewScrollPosition = (scrollPosition) => {
266
+ if (!Array.isArray(scrollPosition)) {
267
+ throw new ExtensionApiError('view scroll position must be an array');
268
+ }
269
+ if (scrollPosition.length === 0) {
270
+ return [];
271
+ }
272
+ if (scrollPosition.length !== 2) {
273
+ throw new ExtensionApiError('view scroll position must contain a selector and scroll top');
274
+ }
275
+ assertString(scrollPosition[0], 'view scroll position is missing selector');
276
+ assertNumber(scrollPosition[1], 'view scroll position is missing scroll top');
277
+ return [scrollPosition[0], scrollPosition[1]];
278
+ };
265
279
  const renderPatches = async (uid, instance) => {
266
280
  const oldDom = renderedDoms[uid] || [];
267
281
  const newDom = await renderDom(instance);
@@ -374,10 +388,24 @@ const withSelections = async (result, instance) => {
374
388
  selections,
375
389
  };
376
390
  };
391
+ const withScrollPosition = async (result, instance) => {
392
+ if (typeof instance.renderScrollPosition !== 'function') {
393
+ return result;
394
+ }
395
+ const scrollPosition = normalizeViewScrollPosition(await instance.renderScrollPosition());
396
+ if (scrollPosition.length === 0) {
397
+ return result;
398
+ }
399
+ return {
400
+ ...result,
401
+ scrollPosition,
402
+ };
403
+ };
377
404
  const withRenderMetadata = async (result, instance, contextChange) => {
378
405
  const resultWithFocus = await withFocusSelector(result, instance, contextChange);
379
406
  const resultWithSelections = await withSelections(resultWithFocus, instance);
380
- return withTitle(resultWithSelections, instance);
407
+ const resultWithScrollPosition = await withScrollPosition(resultWithSelections, instance);
408
+ return withTitle(resultWithScrollPosition, instance);
381
409
  };
382
410
  const maybeClearContext = async (uid, viewId) => {
383
411
  if (!contexts[uid]) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/api",
3
- "version": "8.50.0",
3
+ "version": "8.52.0",
4
4
  "description": "Tree-shakeable extension API for Lvce Editor extensions.",
5
5
  "keywords": [
6
6
  "lvce-editor",