@mak-98/posix-fs-dirvi-app 0.11.0-beta.2 → 0.11.0-beta.3

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.
@@ -1,12 +1,20 @@
1
1
  import { z } from 'zod';
2
2
  import { NavNode, SerializableKey, State, TreeNode, TreeNodeModel, Folds, FoldsModel, Cursor, StateModel } from 'dirvi-lib';
3
3
  import { UnixPath } from './unix-path.js';
4
- export declare const PosixNameSchema: z.ZodPipe<z.ZodType<SerializableKey, unknown, z.core.$ZodTypeInternals<SerializableKey, unknown>>, z.ZodString>;
5
- export type PosixName = z.output<typeof PosixNameSchema>;
4
+ /**
5
+ * A JavaScript-string representation of a non-special POSIX filename.
6
+ *
7
+ * Validates invariants needed for a tree entry ID, not full POSIX compatibility.
8
+ */
9
+ export declare const PosixFilenameSchema: z.ZodPipe<z.ZodType<SerializableKey, unknown, z.core.$ZodTypeInternals<SerializableKey, unknown>>, z.ZodString>;
10
+ /**
11
+ * `Id` type used for posix-fs-dirvi-app.
12
+ */
13
+ export type PosixId = z.output<typeof PosixFilenameSchema>;
6
14
  /**
7
15
  * POSIX-specific meaning attached to a tree node.
8
16
  */
9
- export type PosixEntry = Readonly<{
17
+ export type PosixValue = Readonly<{
10
18
  kind: 'file';
11
19
  }> | Readonly<{
12
20
  kind: 'symlink';
@@ -14,51 +22,51 @@ export type PosixEntry = Readonly<{
14
22
  }> | Readonly<{
15
23
  kind: 'directory';
16
24
  }>;
17
- export declare const PosixEntrySchema: z.ZodType<PosixEntry>;
25
+ export declare const PosixValueSchema: z.ZodType<PosixValue>;
18
26
  /**
19
27
  * An opaque tree whose IDs are POSIX entry names and whose values describe
20
28
  * POSIX entry semantics.
21
29
  */
22
- export type PosixTreeNode = TreeNode<PosixName, PosixEntry>;
30
+ export type PosixTreeNode = TreeNode<PosixId, PosixValue>;
23
31
  export declare const PosixTreeNodeApi: Readonly<{
24
- createLeaf(id: string, value: PosixEntry): TreeNode<string, PosixEntry>;
25
- createUnloadedBranch(id: string, value: PosixEntry): TreeNode<string, PosixEntry>;
26
- createLoadedBranch(id: string, value: PosixEntry, children: Iterable<TreeNode<string, PosixEntry>>): TreeNode<string, PosixEntry> | undefined;
27
- id(node: TreeNode<string, PosixEntry>): string;
28
- value(node: TreeNode<string, PosixEntry>): PosixEntry;
29
- kind(node: TreeNode<string, PosixEntry>): import("dirvi-lib").TreeNodeKind;
30
- match<Result>(node: TreeNode<string, PosixEntry>, handlers: Readonly<{
32
+ createLeaf(id: string, value: PosixValue): TreeNode<string, PosixValue>;
33
+ createUnloadedBranch(id: string, value: PosixValue): TreeNode<string, PosixValue>;
34
+ createLoadedBranch(id: string, value: PosixValue, children: Iterable<TreeNode<string, PosixValue>>): TreeNode<string, PosixValue> | undefined;
35
+ id(node: TreeNode<string, PosixValue>): string;
36
+ value(node: TreeNode<string, PosixValue>): PosixValue;
37
+ kind(node: TreeNode<string, PosixValue>): import("dirvi-lib").TreeNodeKind;
38
+ matchByKind<Result>(node: TreeNode<string, PosixValue>, handlers: Readonly<{
31
39
  leaf: (node: Readonly<{
32
40
  id: string;
33
- value: PosixEntry;
41
+ value: PosixValue;
34
42
  }>) => Result;
35
43
  unloadedBranch: (node: Readonly<{
36
44
  id: string;
37
- value: PosixEntry;
45
+ value: PosixValue;
38
46
  }>) => Result;
39
47
  loadedBranch: (node: Readonly<{
40
48
  id: string;
41
- value: PosixEntry;
42
- children: Iterable<TreeNode<string, PosixEntry>>;
49
+ value: PosixValue;
50
+ children: Iterable<TreeNode<string, PosixValue>>;
43
51
  }>) => Result;
44
52
  }>): Result;
45
- getLoadedChildren(node: TreeNode<string, PosixEntry>): Iterable<TreeNode<string, PosixEntry>> | undefined;
46
- findChildById(node: TreeNode<string, PosixEntry>, id: string): TreeNode<string, PosixEntry> | undefined;
47
- withValue(node: TreeNode<string, PosixEntry>, value: PosixEntry): TreeNode<string, PosixEntry>;
48
- toLeaf(node: TreeNode<string, PosixEntry>): TreeNode<string, PosixEntry>;
49
- toUnloadedBranch(node: TreeNode<string, PosixEntry>): TreeNode<string, PosixEntry>;
50
- withLoadedChildren(node: TreeNode<string, PosixEntry>, children: Iterable<TreeNode<string, PosixEntry>>): TreeNode<string, PosixEntry> | undefined;
51
- findAtPath(root: TreeNode<string, PosixEntry>, path: readonly string[]): TreeNode<string, PosixEntry> | undefined;
52
- selectAtPath<Result>(root: TreeNode<string, PosixEntry>, path: readonly string[], selector: (node: TreeNode<string, PosixEntry>) => Result): Result | undefined;
53
- updateAtPath(root: TreeNode<string, PosixEntry>, path: readonly string[], update: (node: TreeNode<string, PosixEntry>) => TreeNode<string, PosixEntry> | undefined): TreeNode<string, PosixEntry> | undefined;
54
- toModel(node: TreeNode<string, PosixEntry>): TreeNodeModel<string, PosixEntry>;
55
- fromModel(model: TreeNodeModel<string, PosixEntry>): TreeNode<string, PosixEntry> | undefined;
53
+ getLoadedChildren(node: TreeNode<string, PosixValue>): Iterable<TreeNode<string, PosixValue>> | undefined;
54
+ findChildById(node: TreeNode<string, PosixValue>, id: string): TreeNode<string, PosixValue> | undefined;
55
+ withValue(node: TreeNode<string, PosixValue>, value: PosixValue): TreeNode<string, PosixValue>;
56
+ toLeaf(node: TreeNode<string, PosixValue>): TreeNode<string, PosixValue>;
57
+ toUnloadedBranch(node: TreeNode<string, PosixValue>): TreeNode<string, PosixValue>;
58
+ withLoadedChildren(node: TreeNode<string, PosixValue>, children: Iterable<TreeNode<string, PosixValue>>): TreeNode<string, PosixValue> | undefined;
59
+ findAtPath(root: TreeNode<string, PosixValue>, path: readonly string[]): TreeNode<string, PosixValue> | undefined;
60
+ selectAtPath<Result>(root: TreeNode<string, PosixValue>, path: readonly string[], selector: (node: TreeNode<string, PosixValue>) => Result): Result | undefined;
61
+ updateAtPath(root: TreeNode<string, PosixValue>, path: readonly string[], update: (node: TreeNode<string, PosixValue>) => TreeNode<string, PosixValue> | undefined): TreeNode<string, PosixValue> | undefined;
62
+ toModel(node: TreeNode<string, PosixValue>): TreeNodeModel<string, PosixValue>;
63
+ fromModel(model: TreeNodeModel<string, PosixValue>): TreeNode<string, PosixValue> | undefined;
56
64
  }>;
57
65
  export declare const PosixTreeNode: {
58
- readonly file: (name: PosixName) => PosixTreeNode;
59
- readonly symlink: (name: PosixName, target: UnixPath) => PosixTreeNode;
60
- readonly unloadedDirectory: (name: PosixName) => PosixTreeNode;
61
- readonly loadedDirectory: (name: PosixName, children: Iterable<PosixTreeNode>) => PosixTreeNode | undefined;
66
+ readonly file: (name: PosixId) => PosixTreeNode;
67
+ readonly symlink: (name: PosixId, target: UnixPath) => PosixTreeNode;
68
+ readonly unloadedDirectory: (name: PosixId) => PosixTreeNode;
69
+ readonly loadedDirectory: (name: PosixId, children: Iterable<PosixTreeNode>) => PosixTreeNode | undefined;
62
70
  /**
63
71
  * Runtime domain invariant check.
64
72
  *
@@ -87,7 +95,7 @@ export declare const PosixTreeNode: {
87
95
  * It intentionally exposes `id`, `value`, and `children`, because serialized
88
96
  * data must have a concrete public format.
89
97
  */
90
- export type PosixTreeNodeModel = TreeNodeModel<PosixName, PosixEntry>;
98
+ export type PosixTreeNodeModel = TreeNodeModel<PosixId, PosixValue>;
91
99
  /**
92
100
  * Validates both the generic tree model shape and the POSIX-specific
93
101
  * file/symlink/directory invariants.
@@ -107,7 +115,7 @@ export declare function encodePosixTreeNode(node: PosixTreeNode): PosixTreeNodeM
107
115
  /**
108
116
  * Fold definitions for one POSIX directory tree.
109
117
  */
110
- export type PosixFolds = Folds<PosixName>;
118
+ export type PosixFolds = Folds<PosixId>;
111
119
  export declare const PosixFoldsApi: Readonly<{
112
120
  create(rootId: string, initialPrimaryInfo: Readonly<{
113
121
  name: string;
@@ -192,39 +200,39 @@ export declare const PosixFoldsApi: Readonly<{
192
200
  }> | null)[]];
193
201
  }>): Folds<string> | undefined;
194
202
  }>;
195
- export type PosixFoldsModel = FoldsModel<PosixName>;
203
+ export type PosixFoldsModel = FoldsModel<PosixId>;
196
204
  export declare const PosixFoldsModelSchema: z.ZodType<PosixFoldsModel>;
197
205
  export declare const PosixCursorSchema: z.ZodType<PosixCursor>;
198
- export type PosixCursor = Cursor<PosixName>;
206
+ export type PosixCursor = Cursor<PosixId>;
199
207
  export declare const PosixCursorApi: import("dirvi-lib").CursorApi<string>;
200
208
  /**
201
209
  * NavNode should now be parameterized by node value, not the recursive
202
210
  * application node shape.
203
211
  */
204
- export type PosixNavNode = NavNode<PosixName>;
205
- export declare const PosixNavApi: import("dirvi-lib").NavNodeApi<string, PosixEntry>;
212
+ export type PosixNavNode = NavNode<PosixId>;
213
+ export declare const PosixNavApi: import("dirvi-lib").NavNodeApi<string, PosixValue>;
206
214
  /**
207
215
  * State should now be parameterized by application value, not a recursive
208
216
  * structural node type.
209
217
  */
210
- export type PosixState = State<PosixName, PosixEntry>;
218
+ export type PosixState = State<PosixId, PosixValue>;
211
219
  export declare const PosixStateApi: Readonly<{
212
220
  getNodeAtCursor(state: Readonly<{
213
- root: TreeNode<string, PosixEntry>;
221
+ root: TreeNode<string, PosixValue>;
214
222
  folds: Folds<string>;
215
223
  cursor: Cursor<string>;
216
- }>): TreeNode<string, PosixEntry> | undefined;
224
+ }>): TreeNode<string, PosixValue> | undefined;
217
225
  resync(oldState: Readonly<{
218
- root: TreeNode<string, PosixEntry>;
226
+ root: TreeNode<string, PosixValue>;
219
227
  folds: Folds<string>;
220
228
  cursor: Cursor<string>;
221
- }>, loadBranches: (path: readonly string[]) => Promise<readonly TreeNode<string, PosixEntry>[]>): Promise<Readonly<{
222
- root: TreeNode<string, PosixEntry>;
229
+ }>, loadBranches: (path: readonly string[]) => Promise<readonly TreeNode<string, PosixValue>[]>): Promise<Readonly<{
230
+ root: TreeNode<string, PosixValue>;
223
231
  folds: Folds<string>;
224
232
  cursor: Cursor<string>;
225
233
  }>>;
226
234
  }>;
227
- export type PosixStateModel = StateModel<PosixName, PosixEntry>;
235
+ export type PosixStateModel = StateModel<PosixId, PosixValue>;
228
236
  /**
229
237
  * The state schema should operate on a serializable tree *model*, then decode
230
238
  * it to opaque nodes. Do not try to make Zod construct TreeNode directly.
@@ -1 +1 @@
1
- {"version":3,"file":"posix-tree.d.ts","sourceRoot":"","sources":["../../src/domain/posix-tree.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"posix-tree.d.ts","sourceRoot":"","sources":["../../src/domain/posix-tree.ts"],"names":[],"mappings":"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"}
@@ -2,16 +2,24 @@ import { z } from 'zod';
2
2
  import { serializableKeySchema, createNavNodeApi, createStateApi, createTreeNodeApi, createFoldsApi, createFoldsModelSchema, createCursorSchema, createCursorApi, createStateModelSchema, } from 'dirvi-lib';
3
3
  import { UnixPathSchema } from './unix-path.js';
4
4
  // -----------------------------------------------------------------------------
5
- // PosixName
5
+ // PosixName: Id extends SerializableKey
6
6
  // -----------------------------------------------------------------------------
7
- export const PosixNameSchema = serializableKeySchema.pipe(z
7
+ /**
8
+ * A JavaScript-string representation of a non-special POSIX filename.
9
+ *
10
+ * Validates invariants needed for a tree entry ID, not full POSIX compatibility.
11
+ */
12
+ export const PosixFilenameSchema = serializableKeySchema.pipe(z
8
13
  .string()
9
14
  .min(1, 'Entry name cannot be empty.')
15
+ .refine((value) => !value.includes('\0'), {
16
+ message: 'Entry name must not contain a NUL character.',
17
+ })
10
18
  .refine((value) => !value.includes('/'), {
11
19
  message: "Entry name must not contain '/'.",
12
20
  })
13
21
  .refine((value) => value !== '.' && value !== '..', {
14
- message: "Entry name cannot be '.' or '..'.",
22
+ message: "Entry name must not be '.' or '..'.",
15
23
  }));
16
24
  const PosixFileEntrySchema = z
17
25
  .object({
@@ -29,7 +37,7 @@ const PosixDirectoryEntrySchema = z
29
37
  kind: z.literal('directory'),
30
38
  })
31
39
  .strict();
32
- export const PosixEntrySchema = z.discriminatedUnion('kind', [PosixFileEntrySchema, PosixSymlinkEntrySchema, PosixDirectoryEntrySchema]);
40
+ export const PosixValueSchema = z.discriminatedUnion('kind', [PosixFileEntrySchema, PosixSymlinkEntrySchema, PosixDirectoryEntrySchema]);
33
41
  export const PosixTreeNodeApi = createTreeNodeApi();
34
42
  // -----------------------------------------------------------------------------
35
43
  // POSIX domain constructors
@@ -107,21 +115,21 @@ export const PosixTreeNodeModelSchema = z.lazy(() => z.union([
107
115
  // Leaf: file
108
116
  z
109
117
  .object({
110
- id: PosixNameSchema,
118
+ id: PosixFilenameSchema,
111
119
  value: PosixFileEntrySchema,
112
120
  })
113
121
  .strict(),
114
122
  // Leaf: symlink
115
123
  z
116
124
  .object({
117
- id: PosixNameSchema,
125
+ id: PosixFilenameSchema,
118
126
  value: PosixSymlinkEntrySchema,
119
127
  })
120
128
  .strict(),
121
129
  // Unloaded branch: directory
122
130
  z
123
131
  .object({
124
- id: PosixNameSchema,
132
+ id: PosixFilenameSchema,
125
133
  value: PosixDirectoryEntrySchema,
126
134
  children: z.null(),
127
135
  })
@@ -129,7 +137,7 @@ export const PosixTreeNodeModelSchema = z.lazy(() => z.union([
129
137
  // Loaded branch: directory
130
138
  z
131
139
  .object({
132
- id: PosixNameSchema,
140
+ id: PosixFilenameSchema,
133
141
  value: PosixDirectoryEntrySchema,
134
142
  children: z.array(PosixTreeNodeModelSchema),
135
143
  })
@@ -162,14 +170,14 @@ export function encodePosixTreeNode(node) {
162
170
  */
163
171
  const PosixFoldTreeNodeApi = createTreeNodeApi();
164
172
  export const PosixFoldsApi = createFoldsApi(PosixFoldTreeNodeApi);
165
- export const PosixFoldsModelSchema = createFoldsModelSchema(PosixNameSchema);
173
+ export const PosixFoldsModelSchema = createFoldsModelSchema(PosixFilenameSchema);
166
174
  // -----------------------------------------------------------------------------
167
175
  // PosixCursor
168
176
  // -----------------------------------------------------------------------------
169
- export const PosixCursorSchema = createCursorSchema(PosixNameSchema);
177
+ export const PosixCursorSchema = createCursorSchema(PosixFilenameSchema);
170
178
  export const PosixCursorApi = createCursorApi();
171
179
  export const PosixNavApi = createNavNodeApi(PosixTreeNodeApi, PosixFoldsApi, PosixCursorApi, {
172
- compareEntries(left, right) {
180
+ compareSiblings(left, right) {
173
181
  return left.id.localeCompare(right.id);
174
182
  },
175
183
  });
package/dist/index.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- export { posixAppPlugin as default } from './posix-fs-dirvi-app.js';
2
- export { posixAppPlugin } from './posix-fs-dirvi-app.js';
1
+ export { posixAppPlugin2 as default } from './posix-fs-dirvi-app.js';
2
+ export { posixAppPlugin2 } from './posix-fs-dirvi-app.js';
3
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,IAAI,OAAO,EAAE,MAAM,yBAAyB,CAAC;AACpE,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,IAAI,OAAO,EAAE,MAAM,yBAAyB,CAAC;AACrE,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC"}
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- export { posixAppPlugin as default } from './posix-fs-dirvi-app.js';
2
- export { posixAppPlugin } from './posix-fs-dirvi-app.js';
1
+ export { posixAppPlugin2 as default } from './posix-fs-dirvi-app.js';
2
+ export { posixAppPlugin2 } from './posix-fs-dirvi-app.js';
@@ -1,5 +1,5 @@
1
- import { TreeNode } from 'dirvi-lib';
2
- import { PosixEntry, PosixName } from '../domain/posix-tree.js';
3
- import { UnixAbsolutePath } from '../domain/unix-path.js';
4
- export declare function getDirEntries(address: UnixAbsolutePath): Promise<TreeNode<PosixName, PosixEntry>[]>;
1
+ import type { TreeNode } from 'dirvi-lib';
2
+ import { type PosixValue, type PosixId } from '../domain/posix-tree.js';
3
+ import { type UnixAbsolutePath } from '../domain/unix-path.js';
4
+ export declare function getDirEntries(address: UnixAbsolutePath): Promise<TreeNode<PosixId, PosixValue>[]>;
5
5
  //# sourceMappingURL=get-dir-entries.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"get-dir-entries.d.ts","sourceRoot":"","sources":["../../src/infrastructure/get-dir-entries.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAe,MAAM,WAAW,CAAC;AAClD,OAAO,EACL,UAAU,EACV,SAAS,EAGV,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,gBAAgB,EAAkB,MAAM,wBAAwB,CAAC;AAI1E,wBAAsB,aAAa,CACjC,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,QAAQ,CAAC,SAAS,EAAE,UAAU,CAAC,EAAE,CAAC,CA8B5C"}
1
+ {"version":3,"file":"get-dir-entries.d.ts","sourceRoot":"","sources":["../../src/infrastructure/get-dir-entries.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EACL,KAAK,UAAU,EACf,KAAK,OAAO,EAGb,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,KAAK,gBAAgB,EAAkB,MAAM,wBAAwB,CAAC;AAI/E,wBAAsB,aAAa,CACjC,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAC,EAAE,CAAC,CA8B1C"}
@@ -1,4 +1,4 @@
1
- import { PosixNameSchema, PosixTreeNode, } from '../domain/posix-tree.js';
1
+ import { PosixFilenameSchema, PosixTreeNode, } from '../domain/posix-tree.js';
2
2
  import { UnixPathSchema } from '../domain/unix-path.js';
3
3
  import { readdir, readlink } from 'node:fs/promises';
4
4
  import { join } from 'node:path';
@@ -7,7 +7,7 @@ export async function getDirEntries(address) {
7
7
  withFileTypes: true,
8
8
  });
9
9
  return Promise.all(directoryEntries.map(async (directoryEntry) => {
10
- const id = PosixNameSchema.parse(directoryEntry.name);
10
+ const id = PosixFilenameSchema.parse(directoryEntry.name);
11
11
  if (directoryEntry.isSymbolicLink()) {
12
12
  const target = UnixPathSchema.parse(await readlink(join(address, directoryEntry.name)));
13
13
  return PosixTreeNode.symlink(id, target);
@@ -1,4 +1,4 @@
1
- import { PosixEntry, PosixName } from '../domain/posix-tree.js';
1
+ import { PosixValue, PosixId } from '../domain/posix-tree.js';
2
2
  import { UnixAbsolutePath } from '../domain/unix-path.js';
3
3
  import type { AppApi } from 'dirvi-apis';
4
4
  /**
@@ -6,5 +6,6 @@ import type { AppApi } from 'dirvi-apis';
6
6
  *
7
7
  * @param directory - optional directory path for loading the app not at the cwd.
8
8
  */
9
- export declare function loadNodePosixAppApi(directory?: string): AppApi<PosixName, PosixEntry, UnixAbsolutePath>;
9
+ export declare function loadNodePosixAppApi(directory?: string): AppApi<PosixId, PosixValue, UnixAbsolutePath>;
10
+ export declare function createFsResyncSubscription(directory: string): (listener: () => void) => () => void;
10
11
  //# sourceMappingURL=load-node-posix-app-api.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"load-node-posix-app-api.d.ts","sourceRoot":"","sources":["../../src/infrastructure/load-node-posix-app-api.ts"],"names":[],"mappings":"AAQA,OAAO,EAEL,UAAU,EAEV,SAAS,EAQV,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAwEzC;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,SAAS,CAAC,EAAE,MAAM,GACjB,MAAM,CAAC,SAAS,EAAE,UAAU,EAAE,gBAAgB,CAAC,CA2CjD"}
1
+ {"version":3,"file":"load-node-posix-app-api.d.ts","sourceRoot":"","sources":["../../src/infrastructure/load-node-posix-app-api.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,UAAU,EAEV,OAAO,EAIR,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAwEzC;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,SAAS,CAAC,EAAE,MAAM,GACjB,MAAM,CAAC,OAAO,EAAE,UAAU,EAAE,gBAAgB,CAAC,CA0C/C;AAKD,wBAAgB,0BAA0B,CACxC,SAAS,EAAE,MAAM,GAChB,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,MAAM,IAAI,CA6EtC"}
@@ -2,66 +2,73 @@ import { basename, join } from 'node:path';
2
2
  import { watch } from 'node:fs';
3
3
  import { getUnixAbsPath } from './get-unix-abs-path.js';
4
4
  import { getDirEntries } from './get-dir-entries.js';
5
- import envPaths from 'env-paths';
6
- import { createFileViewApi } from './create-file-view-api.js';
7
- import { createHash } from 'node:crypto';
8
- import { PosixCursorApi, PosixFoldsApi, PosixNameSchema, PosixNavApi, PosixStateModelSchema, PosixTreeNode, PosixTreeNodeApi, } from '../domain/posix-tree.js';
5
+ import { PosixFoldsApi, PosixFilenameSchema, PosixNavApi, PosixTreeNode, } from '../domain/posix-tree.js';
9
6
  import { createAppStateApis } from 'dirvi-lib';
10
7
  // ---*--- App Data ---*---
11
8
  // Paths for app data:
12
- const environmentPaths = envPaths('dirvi');
13
- const posixAppDataDirectory = join(environmentPaths.data, 'apps', 'posix');
14
- const posixAppViewsDirectory = join(posixAppDataDirectory, 'views');
15
- // Helpers for saving app data:
16
- function encodeKey(key) {
17
- return createHash('sha256').update(key).digest('hex');
18
- }
19
- /**
20
- * Persists public POSIX state models while keeping TreeNode and Folds runtime
21
- * representations opaque.
22
- */
23
- const posixStateCodec = {
24
- schema: PosixStateModelSchema,
25
- encode: encodePosixState,
26
- decode: decodePosixState,
27
- };
28
- /**
29
- * Converts opaque POSIX runtime state into its serializable persistence model.
30
- */
31
- function encodePosixState(state) {
32
- return {
33
- root: PosixTreeNodeApi.toModel(state.root),
34
- folds: PosixFoldsApi.toModel(state.folds),
35
- cursor: PosixCursorApi.getPath(state.cursor),
36
- };
37
- }
38
- /**
39
- * Restores opaque POSIX runtime state from a schema-validated model.
40
- *
41
- * `TreeNodeApi.fromModel` performs the structural sibling-ID uniqueness check
42
- * which cannot be fully expressed by the JSON/Zod model schema.
43
- */
44
- function decodePosixState(model) {
45
- const root = PosixTreeNodeApi.fromModel(model.root);
46
- /*
47
- * State requires an open root branch. The POSIX domain additionally requires
48
- * files and symlinks to be leaves, and directories to be branches.
49
- */
50
- if (root === undefined ||
51
- !PosixTreeNode.isValid(root) ||
52
- PosixTreeNodeApi.kind(root) !== 'loaded-branch') {
53
- return undefined;
54
- }
55
- const folds = PosixFoldsApi.fromModel(model.folds);
56
- if (folds === undefined) {
57
- return undefined;
58
- }
59
- return {
60
- root,
61
- folds,
62
- cursor: PosixCursorApi.getPath(model.cursor),
63
- };
64
- }
9
+ // const environmentPaths = envPaths('dirvi');
10
+ // const posixAppDataDirectory = join(environmentPaths.data, 'apps', 'posix');
11
+ // const posixAppViewsDirectory = join(posixAppDataDirectory, 'views');
12
+ //
13
+ // // Helpers for saving app data:
14
+ // function encodeKey(key: UnixAbsolutePath): string {
15
+ // return createHash('sha256').update(key).digest('hex');
16
+ // }
17
+ //
18
+ // /**
19
+ // * Persists public POSIX state models while keeping TreeNode and Folds runtime
20
+ // * representations opaque.
21
+ // */
22
+ // const posixStateCodec: StateCodec<PosixId, PosixValue, PosixStateModel> = {
23
+ // schema: PosixStateModelSchema,
24
+ // encode: encodePosixState,
25
+ // decode: decodePosixState,
26
+ // };
27
+ //
28
+ // /**
29
+ // * Converts opaque POSIX runtime state into its serializable persistence model.
30
+ // */
31
+ // function encodePosixState(state: PosixState): PosixStateModel {
32
+ // return {
33
+ // root: PosixTreeNodeApi.toModel(state.root),
34
+ // folds: PosixFoldsApi.toModel(state.folds),
35
+ // cursor: PosixCursorApi.getPath(state.cursor),
36
+ // };
37
+ // }
38
+ //
39
+ // /**
40
+ // * Restores opaque POSIX runtime state from a schema-validated model.
41
+ // *
42
+ // * `TreeNodeApi.fromModel` performs the structural sibling-ID uniqueness check
43
+ // * which cannot be fully expressed by the JSON/Zod model schema.
44
+ // */
45
+ // function decodePosixState(model: PosixStateModel): PosixState | undefined {
46
+ // const root = PosixTreeNodeApi.fromModel(model.root);
47
+ //
48
+ // /*
49
+ // * State requires an open root branch. The POSIX domain additionally requires
50
+ // * files and symlinks to be leaves, and directories to be branches.
51
+ // */
52
+ // if (
53
+ // root === undefined ||
54
+ // !PosixTreeNode.isValid(root) ||
55
+ // PosixTreeNodeApi.kind(root) !== 'loaded-branch'
56
+ // ) {
57
+ // return undefined;
58
+ // }
59
+ //
60
+ // const folds = PosixFoldsApi.fromModel(model.folds);
61
+ //
62
+ // if (folds === undefined) {
63
+ // return undefined;
64
+ // }
65
+ //
66
+ // return {
67
+ // root,
68
+ // folds,
69
+ // cursor: PosixCursorApi.getPath(model.cursor),
70
+ // };
71
+ // }
65
72
  // --- Creating Posix App API ---
66
73
  /**
67
74
  * Creates the AppApi for the POSIX app.
@@ -70,14 +77,13 @@ function decodePosixState(model) {
70
77
  */
71
78
  export function loadNodePosixAppApi(directory) {
72
79
  const unixAbsPath = getUnixAbsPath(directory ?? process.cwd());
73
- const rootId = PosixNameSchema.parse(basename(unixAbsPath));
80
+ const rootId = PosixFilenameSchema.parse(basename(unixAbsPath));
74
81
  const apis = createAppStateApis();
75
82
  function loadBranches(path) {
76
83
  const address = join(unixAbsPath, ...path);
77
84
  return getDirEntries(address);
78
85
  }
79
86
  return {
80
- appId: 'posix',
81
87
  name: unixAbsPath,
82
88
  rootId,
83
89
  loadBranches,
@@ -92,12 +98,12 @@ export function loadNodePosixAppApi(directory) {
92
98
  },
93
99
  subscribeToResync: createFsResyncSubscription(join(unixAbsPath)),
94
100
  // The key for the Posix app instance is just the directory working in:
95
- viewKey: unixAbsPath,
96
- viewApi: createFileViewApi({
97
- directory: posixAppViewsDirectory,
98
- encodeKey,
99
- stateCodec: posixStateCodec,
100
- }),
101
+ // viewKey: unixAbsPath,
102
+ // viewApi: createFileViewApi({
103
+ // directory: posixAppViewsDirectory,
104
+ // encodeKey,
105
+ // stateCodec: posixStateCodec,
106
+ // }),
101
107
  foldsApi: PosixFoldsApi,
102
108
  navNodeApi: PosixNavApi,
103
109
  ...apis,
@@ -106,7 +112,7 @@ export function loadNodePosixAppApi(directory) {
106
112
  // `recursive: true` is supported by macOS and Windows, but
107
113
  // recursive watching is not supported on all Node/POSIX
108
114
  // platforms: Linux unsupported.
109
- function createFsResyncSubscription(directory) {
115
+ export function createFsResyncSubscription(directory) {
110
116
  const listeners = new Set();
111
117
  let watcher;
112
118
  let notificationTimer;
@@ -1,6 +1,12 @@
1
- import type { AppPlugin } from 'dirvi-apis/plugin';
1
+ import type { AppPlugin, AppPlugin2 } from 'dirvi-apis/plugin';
2
2
  /**
3
3
  * A dirvi app that exposes a POSIX filesystem as a navigable tree.
4
4
  */
5
5
  export declare const posixAppPlugin: AppPlugin;
6
+ /**
7
+ * Creates applicator of AppDefinition.
8
+ *
9
+ * Input for this app is the absolute path to the directory to open on.
10
+ */
11
+ export declare const posixAppPlugin2: AppPlugin2;
6
12
  //# sourceMappingURL=posix-fs-dirvi-app.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"posix-fs-dirvi-app.d.ts","sourceRoot":"","sources":["../src/posix-fs-dirvi-app.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAInD;;GAEG;AACH,eAAO,MAAM,cAAc,EAAE,SAQ5B,CAAC"}
1
+ {"version":3,"file":"posix-fs-dirvi-app.d.ts","sourceRoot":"","sources":["../src/posix-fs-dirvi-app.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAiB,SAAS,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAQ9E;;GAEG;AACH,eAAO,MAAM,cAAc,EAAE,SAQ5B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,eAAe,EAAE,UAiD7B,CAAC"}
@@ -1,4 +1,8 @@
1
- import { loadNodePosixAppApi } from './infrastructure/load-node-posix-app-api.js';
1
+ import { createFsResyncSubscription, loadNodePosixAppApi } from './infrastructure/load-node-posix-app-api.js';
2
+ import { PosixFilenameSchema, PosixValueSchema, PosixTreeNode } from './domain/posix-tree.js';
3
+ import { basename, join } from 'node:path';
4
+ import { getUnixAbsPath } from './infrastructure/get-unix-abs-path.js';
5
+ import { getDirEntries } from './infrastructure/get-dir-entries.js';
2
6
  /**
3
7
  * A dirvi app that exposes a POSIX filesystem as a navigable tree.
4
8
  */
@@ -10,3 +14,43 @@ export const posixAppPlugin = {
10
14
  };
11
15
  },
12
16
  };
17
+ /**
18
+ * Creates applicator of AppDefinition.
19
+ *
20
+ * Input for this app is the absolute path to the directory to open on.
21
+ */
22
+ export const posixAppPlugin2 = {
23
+ createAppDefinitionApplicator: (input) => {
24
+ const unixAbsPath = getUnixAbsPath(input ?? process.cwd());
25
+ const rootId = PosixFilenameSchema.parse(basename(unixAbsPath));
26
+ function loadDirectoryEntries(path) {
27
+ const address = join(unixAbsPath, ...path);
28
+ return getDirEntries(address);
29
+ }
30
+ const appDefinition = {
31
+ displayName: `POSIX: ${input}`,
32
+ rootId,
33
+ idSchema: PosixFilenameSchema,
34
+ valueSchema: PosixValueSchema,
35
+ createRoot: async () => {
36
+ // Start with root branches already loaded
37
+ const rootBranches = await loadDirectoryEntries([]);
38
+ const root = PosixTreeNode.loadedDirectory(rootId, rootBranches);
39
+ if (root === undefined) {
40
+ throw new Error('Cannot create POSIX root: duplicate directory entry names');
41
+ }
42
+ return root;
43
+ },
44
+ loadChildren: loadDirectoryEntries,
45
+ subscribeToResync: createFsResyncSubscription(join(unixAbsPath)),
46
+ createNavNodeApiOptions: {
47
+ compareSiblings: (left, right) => {
48
+ return left.id.localeCompare(right.id);
49
+ },
50
+ },
51
+ };
52
+ return (appDefinitionConsumer) => {
53
+ return appDefinitionConsumer(appDefinition);
54
+ };
55
+ },
56
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mak-98/posix-fs-dirvi-app",
3
- "version": "0.11.0-beta.2",
3
+ "version": "0.11.0-beta.3",
4
4
  "description": "POSIX filesystem app for dirvi.",
5
5
  "license": "GPL-3.0-or-later",
6
6
  "type": "module",
@@ -19,8 +19,8 @@
19
19
  "node": ">=22"
20
20
  },
21
21
  "dependencies": {
22
- "dirvi-apis": "0.11.0-beta.1",
23
- "dirvi-lib": "0.11.0-beta.1",
22
+ "dirvi-apis": "0.11.0-beta.3",
23
+ "dirvi-lib": "0.11.0-beta.3",
24
24
  "zod": "^4.4.3",
25
25
  "env-paths": "^4.0.0"
26
26
  },