dirvi-lib 0.7.0 → 0.8.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.
Files changed (72) hide show
  1. package/dist/index.d.ts +1 -1
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +1 -1
  4. package/dist/tree-surfer/cursor.d.ts +52 -26
  5. package/dist/tree-surfer/cursor.d.ts.map +1 -1
  6. package/dist/tree-surfer/cursor.js +19 -44
  7. package/dist/tree-surfer/fold-node/fold-node.arb.d.ts +2 -0
  8. package/dist/tree-surfer/fold-node/fold-node.arb.d.ts.map +1 -0
  9. package/dist/tree-surfer/fold-node/fold-node.arb.js +1 -0
  10. package/dist/tree-surfer/fold-node/fold-node.impl.d.ts +3 -4
  11. package/dist/tree-surfer/fold-node/fold-node.impl.d.ts.map +1 -1
  12. package/dist/tree-surfer/fold-node/fold-node.impl.js +73 -67
  13. package/dist/tree-surfer/fold-node/fold-node.schema.d.ts +3 -5
  14. package/dist/tree-surfer/fold-node/fold-node.schema.d.ts.map +1 -1
  15. package/dist/tree-surfer/fold-node/fold-node.schema.js +2 -9
  16. package/dist/tree-surfer/fold-node/fold-node.types.d.ts +169 -46
  17. package/dist/tree-surfer/fold-node/fold-node.types.d.ts.map +1 -1
  18. package/dist/tree-surfer/fold-node/tree-node.test.d.ts +2 -0
  19. package/dist/tree-surfer/fold-node/tree-node.test.d.ts.map +1 -0
  20. package/dist/tree-surfer/fold-node/tree-node.test.js +90 -0
  21. package/dist/tree-surfer/index.d.ts +3 -1
  22. package/dist/tree-surfer/index.d.ts.map +1 -1
  23. package/dist/tree-surfer/index.js +3 -1
  24. package/dist/tree-surfer/nav-node/nav-node.impl.d.ts +5 -5
  25. package/dist/tree-surfer/nav-node/nav-node.impl.d.ts.map +1 -1
  26. package/dist/tree-surfer/nav-node/nav-node.impl.js +84 -99
  27. package/dist/tree-surfer/nav-node/nav-node.types.d.ts +62 -34
  28. package/dist/tree-surfer/nav-node/nav-node.types.d.ts.map +1 -1
  29. package/dist/tree-surfer/nav-node/nav-node.types.js +1 -3
  30. package/dist/tree-surfer/state/state.impl.d.ts +7 -0
  31. package/dist/tree-surfer/state/state.impl.d.ts.map +1 -0
  32. package/dist/tree-surfer/state/state.impl.js +89 -0
  33. package/dist/tree-surfer/state/state.schemas.d.ts +9 -0
  34. package/dist/tree-surfer/state/state.schemas.d.ts.map +1 -0
  35. package/dist/tree-surfer/state/state.schemas.js +8 -0
  36. package/dist/tree-surfer/state/state.types.d.ts +21 -0
  37. package/dist/tree-surfer/state/state.types.d.ts.map +1 -0
  38. package/dist/tree-surfer/state/state.types.js +1 -0
  39. package/dist/tree-surfer/tree-node/tree-node.arb.d.ts +82 -17
  40. package/dist/tree-surfer/tree-node/tree-node.arb.d.ts.map +1 -1
  41. package/dist/tree-surfer/tree-node/tree-node.arb.debug.test.d.ts +2 -0
  42. package/dist/tree-surfer/tree-node/tree-node.arb.debug.test.d.ts.map +1 -0
  43. package/dist/tree-surfer/tree-node/tree-node.arb.debug.test.js +34 -0
  44. package/dist/tree-surfer/tree-node/tree-node.arb.js +164 -56
  45. package/dist/tree-surfer/tree-node/tree-node.impl.d.ts +1 -1
  46. package/dist/tree-surfer/tree-node/tree-node.impl.d.ts.map +1 -1
  47. package/dist/tree-surfer/tree-node/tree-node.impl.js +41 -48
  48. package/dist/tree-surfer/tree-node/tree-node.schemas.d.ts +2 -2
  49. package/dist/tree-surfer/tree-node/tree-node.schemas.d.ts.map +1 -1
  50. package/dist/tree-surfer/tree-node/tree-node.schemas.js +2 -2
  51. package/dist/tree-surfer/tree-node/tree-node.test.js +144 -76
  52. package/dist/tree-surfer/tree-node/tree-node.types.d.ts +89 -107
  53. package/dist/tree-surfer/tree-node/tree-node.types.d.ts.map +1 -1
  54. package/dist/tree-surfer-ui/application/intent-to-effect.d.ts +6 -2
  55. package/dist/tree-surfer-ui/application/intent-to-effect.d.ts.map +1 -1
  56. package/dist/tree-surfer-ui/application/intent-to-effect.js +1 -6
  57. package/dist/tree-surfer-ui/application/user-input-to-intent.d.ts +10 -2
  58. package/dist/tree-surfer-ui/application/user-input-to-intent.d.ts.map +1 -1
  59. package/dist/tree-surfer-ui/application/user-input-to-intent.js +12 -5
  60. package/dist/tree-surfer-ui/domain/effect.d.ts +9 -8
  61. package/dist/tree-surfer-ui/domain/effect.d.ts.map +1 -1
  62. package/dist/tree-surfer-ui/domain/index.d.ts +1 -1
  63. package/dist/tree-surfer-ui/domain/index.d.ts.map +1 -1
  64. package/dist/tree-surfer-ui/domain/index.js +1 -1
  65. package/dist/tree-surfer-ui/domain/{input-state.d.ts → input-mode-state.d.ts} +2 -2
  66. package/dist/tree-surfer-ui/domain/input-mode-state.d.ts.map +1 -0
  67. package/package.json +3 -2
  68. package/dist/tree-surfer/state.d.ts +0 -25
  69. package/dist/tree-surfer/state.d.ts.map +0 -1
  70. package/dist/tree-surfer/state.js +0 -118
  71. package/dist/tree-surfer-ui/domain/input-state.d.ts.map +0 -1
  72. /package/dist/tree-surfer-ui/domain/{input-state.js → input-mode-state.js} +0 -0
@@ -1,11 +1,14 @@
1
- import type { InputState } from './input-state.js';
1
+ import type { InputModeState } from './input-mode-state.js';
2
2
  import { SerializableKey, TreeNode } from '../../tree-surfer/index.js';
3
- export type Effect<Id extends SerializableKey, BufferNode extends TreeNode<Id, BufferNode>> = {
3
+ export type Effect<Id extends SerializableKey, Node extends TreeNode<Id, Node>> = {
4
4
  effectType: 'dispatchEffectAction';
5
- action: EffectAction<Id, BufferNode>;
5
+ action: EffectAction<Id, Node>;
6
6
  } | {
7
7
  effectType: 'loadBranchEntries';
8
8
  path: Id[];
9
+ } | {
10
+ effectType: 'peekFold';
11
+ parentPath: readonly Id[];
9
12
  } | {
10
13
  effectType: 'saveView';
11
14
  name: string;
@@ -20,23 +23,21 @@ export type Effect<Id extends SerializableKey, BufferNode extends TreeNode<Id, B
20
23
  exitMessage: string;
21
24
  } | {
22
25
  effectType: 'setInputState';
23
- inputState: InputState;
26
+ inputState: InputModeState;
24
27
  };
25
- export type EffectAction<Id extends SerializableKey, BufferNode extends TreeNode<Id, BufferNode>> = {
28
+ export type EffectAction<Id extends SerializableKey, Node extends TreeNode<Id, Node>> = {
26
29
  effectActionType: 'nextEntry';
27
30
  } | {
28
31
  effectActionType: 'prevEntry';
29
32
  } | {
30
33
  effectActionType: 'setBranchEntries';
31
34
  path: Id[];
32
- entries: BufferNode[] | null;
35
+ entries: Node[] | null;
33
36
  } | {
34
37
  effectActionType: 'navigateToParent';
35
38
  } | {
36
39
  effectActionType: 'fold';
37
40
  } | {
38
41
  effectActionType: 'unfold';
39
- } | {
40
- effectActionType: 'toggleFold';
41
42
  };
42
43
  //# sourceMappingURL=effect.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"effect.d.ts","sourceRoot":"","sources":["../../../src/tree-surfer-ui/domain/effect.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAEvE,MAAM,MAAM,MAAM,CAChB,EAAE,SAAS,eAAe,EAC1B,UAAU,SAAS,QAAQ,CAAC,EAAE,EAAE,UAAU,CAAC,IAEzC;IACE,UAAU,EAAE,sBAAsB,CAAC;IACnC,MAAM,EAAE,YAAY,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC;CACtC,GACD;IACE,UAAU,EAAE,mBAAmB,CAAC;IAChC,IAAI,EAAE,EAAE,EAAE,CAAC;CACZ,GACD;IACE,UAAU,EAAE,UAAU,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,OAAO,CAAC;CACpB,GACD;IACE,UAAU,EAAE,UAAU,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;CACd,GACD;IACE,UAAU,EAAE,wBAAwB,CAAC;CACtC,GACD;IACE,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;CACrB,GACD;IACE,UAAU,EAAE,eAAe,CAAC;IAC5B,UAAU,EAAE,UAAU,CAAC;CACxB,CAAC;AAGN,MAAM,MAAM,YAAY,CACtB,EAAE,SAAS,eAAe,EAC1B,UAAU,SAAS,QAAQ,CAAC,EAAE,EAAE,UAAU,CAAC,IAEzC;IACE,gBAAgB,EAAE,WAAW,CAAC;CAC/B,GACD;IACE,gBAAgB,EAAE,WAAW,CAAC;CAC/B,GACD;IACE,gBAAgB,EAAE,kBAAkB,CAAC;IACrC,IAAI,EAAE,EAAE,EAAE,CAAC;IACX,OAAO,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC;CAC9B,GACD;IACE,gBAAgB,EAAE,kBAAkB,CAAC;CACtC,GACD;IACE,gBAAgB,EAAE,MAAM,CAAC;CAC1B,GACD;IACE,gBAAgB,EAAE,QAAQ,CAAC;CAC5B,GACD;IACE,gBAAgB,EAAE,YAAY,CAAC;CAChC,CAAC"}
1
+ {"version":3,"file":"effect.d.ts","sourceRoot":"","sources":["../../../src/tree-surfer-ui/domain/effect.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAEvE,MAAM,MAAM,MAAM,CAChB,EAAE,SAAS,eAAe,EAC1B,IAAI,SAAS,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC,IAE7B;IACE,UAAU,EAAE,sBAAsB,CAAC;IACnC,MAAM,EAAE,YAAY,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;CAChC,GACD;IACE,UAAU,EAAE,mBAAmB,CAAC;IAChC,IAAI,EAAE,EAAE,EAAE,CAAC;CACZ,GACD;IACE,UAAU,EAAE,UAAU,CAAC;IACvB,UAAU,EAAE,SAAS,EAAE,EAAE,CAAC;CAC3B,GACD;IACE,UAAU,EAAE,UAAU,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,OAAO,CAAC;CACpB,GACD;IACE,UAAU,EAAE,UAAU,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;CACd,GACD;IACE,UAAU,EAAE,wBAAwB,CAAC;CACtC,GACD;IACE,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;CACrB,GACD;IACE,UAAU,EAAE,eAAe,CAAC;IAC5B,UAAU,EAAE,cAAc,CAAC;CAC5B,CAAC;AAGN,MAAM,MAAM,YAAY,CACtB,EAAE,SAAS,eAAe,EAC1B,IAAI,SAAS,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC,IAE7B;IACE,gBAAgB,EAAE,WAAW,CAAC;CAC/B,GACD;IACE,gBAAgB,EAAE,WAAW,CAAC;CAC/B,GACD;IACE,gBAAgB,EAAE,kBAAkB,CAAC;IACrC,IAAI,EAAE,EAAE,EAAE,CAAC;IACX,OAAO,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC;CACxB,GACD;IACE,gBAAgB,EAAE,kBAAkB,CAAC;CACtC,GACD;IACE,gBAAgB,EAAE,MAAM,CAAC;CAC1B,GACD;IACE,gBAAgB,EAAE,QAAQ,CAAC;CAC5B,CAAC"}
@@ -1,5 +1,5 @@
1
1
  export * from './effect.js';
2
- export * from './input-state.js';
2
+ export * from './input-mode-state.js';
3
3
  export * from './intent.js';
4
4
  export * from './user-input.js';
5
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tree-surfer-ui/domain/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,kBAAkB,CAAC;AACjC,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tree-surfer-ui/domain/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,uBAAuB,CAAC;AACtC,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC"}
@@ -1,4 +1,4 @@
1
1
  export * from './effect.js';
2
- export * from './input-state.js';
2
+ export * from './input-mode-state.js';
3
3
  export * from './intent.js';
4
4
  export * from './user-input.js';
@@ -1,8 +1,8 @@
1
- export type InputState = {
1
+ export type InputModeState = {
2
2
  inputMode: 'normal';
3
3
  normalBuffer: string;
4
4
  } | {
5
5
  inputMode: 'command';
6
6
  commandLine: string;
7
7
  };
8
- //# sourceMappingURL=input-state.d.ts.map
8
+ //# sourceMappingURL=input-mode-state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"input-mode-state.d.ts","sourceRoot":"","sources":["../../../src/tree-surfer-ui/domain/input-mode-state.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,cAAc,GACtB;IACE,SAAS,EAAE,QAAQ,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;CACtB,GACD;IACE,SAAS,EAAE,SAAS,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dirvi-lib",
3
- "version": "0.7.0",
3
+ "version": "0.8.0",
4
4
  "description": "Dependency for dirvi apps.",
5
5
  "license": "LGPL-3.0-or-later",
6
6
  "type": "module",
@@ -20,6 +20,7 @@
20
20
  "clean": "rm -rf dist",
21
21
  "build": "pnpm clean && tsc",
22
22
  "typecheck": "tsc --noEmit",
23
- "format": "prettier . --write"
23
+ "format": "prettier . --write",
24
+ "docs": "typedoc"
24
25
  }
25
26
  }
@@ -1,25 +0,0 @@
1
- import { z } from 'zod';
2
- import { Cursor, CursorApi } from './cursor.js';
3
- import { SerializableKey, TreeNode, TreeNodeApi } from './tree-node/tree-node.types.js';
4
- import { FoldNodeApi, FoldNodeRoot } from './fold-node/fold-node.types.js';
5
- import { NavNodeApi } from './nav-node/nav-node.types.js';
6
- export declare function createStateSchema<Id extends SerializableKey, BufferNode extends TreeNode<Id, BufferNode>>(bufferNodeSchema: z.ZodType<BufferNode>, foldNodeRootSchema: z.ZodType<State<Id, BufferNode>['foldNode']>, cursorSchema: z.ZodType<State<Id, BufferNode>['cursor']>): z.ZodObject<{
7
- buffer: z.ZodArray<z.ZodType<BufferNode, unknown, z.core.$ZodTypeInternals<BufferNode, unknown>>>;
8
- foldNode: z.ZodType<FoldNodeRoot<Id>, unknown, z.core.$ZodTypeInternals<FoldNodeRoot<Id>, unknown>>;
9
- cursor: z.ZodType<Cursor<Id>, unknown, z.core.$ZodTypeInternals<Cursor<Id>, unknown>>;
10
- }, z.core.$strip>;
11
- export type State<Id extends SerializableKey, BufferNode extends TreeNode<Id, BufferNode>> = {
12
- buffer: BufferNode[];
13
- foldNode: FoldNodeRoot<Id>;
14
- cursor: Cursor<Id>;
15
- };
16
- export type StateApi<Id extends SerializableKey, BufferNode extends TreeNode<Id, BufferNode>> = {
17
- getNodeAtCursor(state: State<Id, BufferNode>): BufferNode | undefined;
18
- /**
19
- * Reloads the root and all descendant branches that were loaded in the
20
- * previous state.
21
- */
22
- resync(oldState: State<Id, BufferNode>, loadBranches: (path: Id[]) => Promise<BufferNode[]>): Promise<State<Id, BufferNode>>;
23
- };
24
- export declare function createStateApi<Id extends SerializableKey, BufferNode extends TreeNode<Id, BufferNode>>(treeNodeApi: TreeNodeApi<Id, BufferNode>, foldNodeApi: FoldNodeApi<Id>, cursorApi: CursorApi<Id>, navNodeApi: NavNodeApi<Id, BufferNode>): StateApi<Id, BufferNode>;
25
- //# sourceMappingURL=state.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../src/tree-surfer/state.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,MAAM,EAAE,SAAS,EAAc,MAAM,aAAa,CAAC;AAC5D,OAAO,EACL,eAAe,EACf,QAAQ,EACR,WAAW,EACZ,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAEL,WAAW,EACX,YAAY,EACb,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAG1D,wBAAgB,iBAAiB,CAC/B,EAAE,SAAS,eAAe,EAC1B,UAAU,SAAS,QAAQ,CAAC,EAAE,EAAE,UAAU,CAAC,EAE3C,gBAAgB,EAAE,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,EACvC,kBAAkB,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC,UAAU,CAAC,CAAC,EAChE,YAAY,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC,QAAQ,CAAC,CAAC;;;;kBAOzD;AAGD,MAAM,MAAM,KAAK,CACf,EAAE,SAAS,eAAe,EAC1B,UAAU,SAAS,QAAQ,CAAC,EAAE,EAAE,UAAU,CAAC,IACzC;IACF,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,QAAQ,EAAE,YAAY,CAAC,EAAE,CAAC,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,QAAQ,CAClB,EAAE,SAAS,eAAe,EAC1B,UAAU,SAAS,QAAQ,CAAC,EAAE,EAAE,UAAU,CAAC,IACzC;IACF,eAAe,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,EAAE,UAAU,CAAC,GAAG,UAAU,GAAG,SAAS,CAAC;IAEtE;;;OAGG;IACH,MAAM,CACJ,QAAQ,EAAE,KAAK,CAAC,EAAE,EAAE,UAAU,CAAC,EAC/B,YAAY,EAAE,CAAC,IAAI,EAAE,EAAE,EAAE,KAAK,OAAO,CAAC,UAAU,EAAE,CAAC,GAClD,OAAO,CAAC,KAAK,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC,CAAC;CACnC,CAAC;AAEF,wBAAgB,cAAc,CAC5B,EAAE,SAAS,eAAe,EAC1B,UAAU,SAAS,QAAQ,CAAC,EAAE,EAAE,UAAU,CAAC,EAE3C,WAAW,EAAE,WAAW,CAAC,EAAE,EAAE,UAAU,CAAC,EACxC,WAAW,EAAE,WAAW,CAAC,EAAE,CAAC,EAC5B,SAAS,EAAE,SAAS,CAAC,EAAE,CAAC,EACxB,UAAU,EAAE,UAAU,CAAC,EAAE,EAAE,UAAU,CAAC,GACrC,QAAQ,CAAC,EAAE,EAAE,UAAU,CAAC,CAgK1B"}
@@ -1,118 +0,0 @@
1
- import { z } from 'zod';
2
- import { CursorKind } from './cursor.js';
3
- // Schema
4
- export function createStateSchema(bufferNodeSchema, foldNodeRootSchema, cursorSchema) {
5
- return z.object({
6
- buffer: z.array(bufferNodeSchema),
7
- foldNode: foldNodeRootSchema,
8
- cursor: cursorSchema,
9
- });
10
- }
11
- export function createStateApi(treeNodeApi, foldNodeApi, cursorApi, navNodeApi) {
12
- // Helpers
13
- /**
14
- * Create a new buffer and fold node at this level.
15
- *
16
- * Works on fold root and child level through the generic.
17
- */
18
- async function reload(oldBuffer, oldFoldNode, // Can be FoldNode too
19
- parentPath, loadBranches) {
20
- let newBufferAtRoot = await loadBranches(parentPath);
21
- let newFoldNode = oldFoldNode; // Start with assumption of no changes
22
- /**
23
- * Reload descendants that were already loaded in the old buffer.
24
- *
25
- * Fold membership is represented by IDs in `folds`, so it remains
26
- * valid across a reload without rebuilding an entry array.
27
- */
28
- for (const oldEntry of oldBuffer) {
29
- // If it wasn't an open branch, then there's no need to reload descendants.
30
- // Either the new entry is a leaf or an unopen branch.
31
- if (!treeNodeApi.isBranch(oldEntry) ||
32
- !treeNodeApi.isOpenBranch(oldEntry)) {
33
- continue;
34
- }
35
- // Get the entry being updated, in the new buffer
36
- const newEntry = treeNodeApi.getAtPath(newBufferAtRoot, [oldEntry.id], (entry) => entry);
37
- // If it doesn't exist (an open branch was deleted) then move on
38
- if (newEntry === undefined) {
39
- continue;
40
- }
41
- // The old entry may have changed into a leaf.
42
- // A newly loaded branch is normally closed here because loadBranches
43
- // returns flat entries, and the descendants are to be attached below.
44
- if (!treeNodeApi.isBranch(newEntry)) {
45
- continue;
46
- }
47
- const oldChildFoldNode = oldFoldNode === undefined
48
- ? undefined
49
- : foldNodeApi.getChildById(oldFoldNode, oldEntry.id);
50
- const entryPath = [...parentPath, oldEntry.id];
51
- const reloadedChild = await reload([...treeNodeApi.getChildren(oldEntry)], oldChildFoldNode, entryPath, loadBranches);
52
- const updatedBuffer = treeNodeApi.modifyAtPath(newBufferAtRoot, [oldEntry.id], (entry) => {
53
- // The entry may be closed: loadBranches normally returns branches
54
- // with `branches: null`. We are turning it back into an open branch.
55
- if (!treeNodeApi.isBranch(entry)) {
56
- return undefined;
57
- }
58
- return {
59
- ...entry,
60
- branches: reloadedChild.buffer,
61
- };
62
- });
63
- if (updatedBuffer !== undefined) {
64
- newBufferAtRoot = updatedBuffer;
65
- }
66
- }
67
- return {
68
- buffer: newBufferAtRoot,
69
- foldNode: newFoldNode,
70
- };
71
- }
72
- /**
73
- * Currently the cursor just goes to the first entry at root if
74
- * not all root entries are folded, otherwise the fold.
75
- *
76
- * TODO: Cursor policy:
77
- * 1. Keep the exact cursor if it survives,
78
- * 2. Otherwise, choose the deepest surviving ancestor entry,
79
- * 3. Otherwise, choose the nearest preceding old cursor that still survives,
80
- * 4. Otherwise, choose the first new cursor.
81
- * 5. If no cursor exists, use the root fold cursor.
82
- */
83
- function resyncCursor(oldState, newBuffer, newFoldNode) {
84
- const navigation = navNodeApi.from(newBuffer, newFoldNode);
85
- return navNodeApi.cursors(navigation)[0];
86
- }
87
- return {
88
- getNodeAtCursor(state) {
89
- const path = cursorApi.getPath(state.cursor);
90
- if (path === undefined) {
91
- // The cursor is positioned on a fold rather than an entry.
92
- return undefined;
93
- }
94
- return treeNodeApi.getAtPath(state.buffer, path, (node) => node);
95
- },
96
- async resync(oldState, loadBranches) {
97
- const reloaded = await reload(oldState.buffer, oldState.foldNode, [], loadBranches);
98
- /*
99
- * `oldState.foldNode` is always present. At the root reload starts with
100
- * that node, so `reloaded.foldNode` should also always be present.
101
- *
102
- * The fallback expresses the State invariant while satisfying the
103
- * optional return type needed by recursive child reloads.
104
- */
105
- const foldNode = reloaded.foldNode ?? oldState.foldNode;
106
- const cursor = resyncCursor(oldState, reloaded.buffer, foldNode) ?? {
107
- kind: CursorKind.Fold,
108
- parentPath: [],
109
- };
110
- return {
111
- ...oldState,
112
- buffer: reloaded.buffer,
113
- foldNode,
114
- cursor,
115
- };
116
- },
117
- };
118
- }
@@ -1 +0,0 @@
1
- {"version":3,"file":"input-state.d.ts","sourceRoot":"","sources":["../../../src/tree-surfer-ui/domain/input-state.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,GAClB;IACE,SAAS,EAAE,QAAQ,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;CACtB,GACD;IACE,SAAS,EAAE,SAAS,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC"}