@skenora/workspace 0.1.2

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/README.md ADDED
@@ -0,0 +1,22 @@
1
+ # @skenora/workspace
2
+
3
+ Local-first workspace sources and sessions for Skenora scene files and model
4
+ bundles.
5
+
6
+ ```bash
7
+ pnpm add @skenora/workspace
8
+ ```
9
+
10
+ The package provides:
11
+
12
+ - `DirectoryWorkspaceSource` for user-authorized directory handles;
13
+ - `FileListWorkspaceSource` for read-only browser file selections;
14
+ - `MemoryWorkspaceSource` for temporary scenes and tests;
15
+ - `WorkspaceSession` for scene discovery, import rollback, save conflict
16
+ detection, and checkpoints;
17
+ - normalized workspace path and index helpers.
18
+
19
+ Workspace owns file organization and persistence. Resource acquisition and
20
+ Blob URL lifetime belong to `@skenora/resources`.
21
+
22
+ See the [SDK guide](https://github.com/zhangjiadi225/skenora/blob/main/docs/SDK.md).
@@ -0,0 +1,60 @@
1
+ export interface WorkspaceEntry {
2
+ path: string;
3
+ name: string;
4
+ kind: "file" | "directory";
5
+ size?: number;
6
+ lastModified?: number;
7
+ }
8
+ export interface WorkspaceSource {
9
+ readonly writable: boolean;
10
+ list(prefix?: string): Promise<readonly WorkspaceEntry[]>;
11
+ has(path: string): Promise<boolean>;
12
+ read(path: string): Promise<File>;
13
+ write?(path: string, data: Blob | string): Promise<void>;
14
+ writeAtomic?(path: string, data: Blob | string): Promise<void>;
15
+ remove?(path: string): Promise<void>;
16
+ }
17
+ export declare const DEFAULT_IGNORED_WORKSPACE_NAMES: readonly string[];
18
+ export interface DirectoryWorkspaceSourceOptions {
19
+ writable?: boolean;
20
+ ignoredNames?: Iterable<string>;
21
+ }
22
+ export interface DirectoryFileHandleLike {
23
+ readonly kind: "file";
24
+ readonly name: string;
25
+ getFile(): Promise<File>;
26
+ createWritable?(): Promise<{
27
+ write(data: Blob | string): Promise<void>;
28
+ close(): Promise<void>;
29
+ }>;
30
+ }
31
+ export interface DirectoryHandleLike {
32
+ readonly kind: "directory";
33
+ readonly name: string;
34
+ entries(): AsyncIterableIterator<[
35
+ string,
36
+ DirectoryFileHandleLike | DirectoryHandleLike
37
+ ]>;
38
+ getFileHandle(name: string, options?: {
39
+ create?: boolean;
40
+ }): Promise<DirectoryFileHandleLike>;
41
+ getDirectoryHandle(name: string, options?: {
42
+ create?: boolean;
43
+ }): Promise<DirectoryHandleLike>;
44
+ removeEntry?(name: string, options?: {
45
+ recursive?: boolean;
46
+ }): Promise<void>;
47
+ }
48
+ export declare class DirectoryWorkspaceSource implements WorkspaceSource {
49
+ #private;
50
+ readonly writable: boolean;
51
+ constructor(root: DirectoryHandleLike, options?: DirectoryWorkspaceSourceOptions);
52
+ list(prefix?: string): Promise<readonly WorkspaceEntry[]>;
53
+ has(path: string): Promise<boolean>;
54
+ read(path: string): Promise<File>;
55
+ write(path: string, data: Blob | string): Promise<void>;
56
+ writeAtomic(path: string, data: Blob | string): Promise<void>;
57
+ remove(path: string): Promise<void>;
58
+ }
59
+ export declare function isIgnoredWorkspacePath(path: string, ignoredNames: ReadonlySet<string>): boolean;
60
+ //# sourceMappingURL=directory-source.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"directory-source.d.ts","sourceRoot":"","sources":["../src/directory-source.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,134 @@
1
+ import { normalizeWorkspacePath } from "./path.js";
2
+ export const DEFAULT_IGNORED_WORKSPACE_NAMES = Object.freeze([
3
+ ".git",
4
+ ".DS_Store",
5
+ "Thumbs.db",
6
+ "node_modules",
7
+ ]);
8
+ export class DirectoryWorkspaceSource {
9
+ writable;
10
+ #root;
11
+ #ignoredNames;
12
+ constructor(root, options = {}) {
13
+ this.#root = root;
14
+ this.writable = options.writable ?? true;
15
+ this.#ignoredNames = new Set([
16
+ ...DEFAULT_IGNORED_WORKSPACE_NAMES,
17
+ ...(options.ignoredNames ?? []),
18
+ ]);
19
+ }
20
+ async list(prefix) {
21
+ const entries = [];
22
+ const start = prefix ? normalizeWorkspacePath(prefix) : "";
23
+ const directory = start
24
+ ? await this.#resolveDirectory(start, false)
25
+ : this.#root;
26
+ await this.#walk(directory, start, entries);
27
+ return entries;
28
+ }
29
+ async has(path) {
30
+ try {
31
+ await this.#resolveFile(normalizeWorkspacePath(path), false);
32
+ return true;
33
+ }
34
+ catch (error) {
35
+ if (isMissingEntryError(error))
36
+ return false;
37
+ throw error;
38
+ }
39
+ }
40
+ async read(path) {
41
+ const handle = await this.#resolveFile(normalizeWorkspacePath(path), false);
42
+ return handle.getFile();
43
+ }
44
+ async write(path, data) {
45
+ if (!this.writable)
46
+ throw new Error("Workspace is read-only");
47
+ const handle = await this.#resolveFile(normalizeWorkspacePath(path), true);
48
+ if (!handle.createWritable) {
49
+ throw new Error("Directory handle does not support writing");
50
+ }
51
+ const writer = await handle.createWritable();
52
+ let writeError = null;
53
+ try {
54
+ await writer.write(data);
55
+ }
56
+ catch (error) {
57
+ writeError = error;
58
+ }
59
+ try {
60
+ await writer.close();
61
+ }
62
+ catch (closeError) {
63
+ if (writeError !== null) {
64
+ throw new AggregateError([writeError, closeError], `Workspace write and close both failed: ${path}`);
65
+ }
66
+ throw closeError;
67
+ }
68
+ if (writeError !== null)
69
+ throw writeError;
70
+ }
71
+ async writeAtomic(path, data) {
72
+ await this.write(path, data);
73
+ }
74
+ async remove(path) {
75
+ if (!this.writable)
76
+ throw new Error("Workspace is read-only");
77
+ const normalized = normalizeWorkspacePath(path);
78
+ const segments = normalized.split("/");
79
+ const name = segments.pop();
80
+ if (!name)
81
+ throw new Error(`Invalid file path: ${normalized}`);
82
+ const directory = await this.#resolveDirectory(segments.join("/"), false);
83
+ if (!directory.removeEntry) {
84
+ throw new Error("Directory handle does not support file removal");
85
+ }
86
+ await directory.removeEntry(name);
87
+ }
88
+ async #walk(directory, prefix, output) {
89
+ for await (const [name, handle] of directory.entries()) {
90
+ if (this.#ignoredNames.has(name))
91
+ continue;
92
+ const path = prefix ? `${prefix}/${name}` : name;
93
+ if (handle.kind === "directory") {
94
+ output.push({ path, name, kind: "directory" });
95
+ await this.#walk(handle, path, output);
96
+ }
97
+ else {
98
+ const file = await handle.getFile();
99
+ output.push({
100
+ path,
101
+ name,
102
+ kind: "file",
103
+ size: file.size,
104
+ lastModified: file.lastModified,
105
+ });
106
+ }
107
+ }
108
+ }
109
+ async #resolveDirectory(path, create) {
110
+ let current = this.#root;
111
+ for (const segment of path.split("/").filter(Boolean)) {
112
+ current = await current.getDirectoryHandle(segment, { create });
113
+ }
114
+ return current;
115
+ }
116
+ async #resolveFile(path, create) {
117
+ const segments = path.split("/");
118
+ const name = segments.pop();
119
+ if (!name)
120
+ throw new Error(`Invalid file path: ${path}`);
121
+ const directory = await this.#resolveDirectory(segments.join("/"), create);
122
+ return directory.getFileHandle(name, { create });
123
+ }
124
+ }
125
+ export function isIgnoredWorkspacePath(path, ignoredNames) {
126
+ return normalizeWorkspacePath(path)
127
+ .split("/")
128
+ .some((segment) => ignoredNames.has(segment));
129
+ }
130
+ function isMissingEntryError(error) {
131
+ const name = error?.name;
132
+ return name === "NotFoundError" || name === "TypeMismatchError";
133
+ }
134
+ //# sourceMappingURL=directory-source.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"directory-source.js","sourceRoot":"","sources":["../src/directory-source.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import { type WorkspaceEntry, type WorkspaceSource } from "./directory-source.js";
2
+ export interface FileListWorkspaceSourceOptions {
3
+ ignoredNames?: Iterable<string>;
4
+ }
5
+ /** Read-only adapter for input[type=file][webkitdirectory] and drag/drop files. */
6
+ export declare class FileListWorkspaceSource implements WorkspaceSource {
7
+ #private;
8
+ readonly writable = false;
9
+ constructor(files: Iterable<File> | ArrayLike<File>, options?: FileListWorkspaceSourceOptions);
10
+ list(prefix?: string): Promise<readonly WorkspaceEntry[]>;
11
+ has(path: string): Promise<boolean>;
12
+ read(path: string): Promise<File>;
13
+ }
14
+ //# sourceMappingURL=file-list-source.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-list-source.d.ts","sourceRoot":"","sources":["../src/file-list-source.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,cAAc,EACnB,KAAK,eAAe,EACrB,MAAM,oBAAoB,CAAC;AAK5B,MAAM,WAAW,8BAA8B;IAC7C,YAAY,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;CACjC;AAED,mFAAmF;AACnF,qBAAa,uBAAwB,YAAW,eAAe;;IAC7D,QAAQ,CAAC,QAAQ,SAAS;gBAIxB,KAAK,EAAE,QAAQ,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,EACvC,OAAO,GAAE,8BAAmC;IA8BxC,IAAI,CAAC,MAAM,SAAK,GAAG,OAAO,CAAC,SAAS,cAAc,EAAE,CAAC;IAkBrD,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAInC,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAMxC"}
@@ -0,0 +1,64 @@
1
+ import { DEFAULT_IGNORED_WORKSPACE_NAMES, isIgnoredWorkspacePath, } from "./directory-source.js";
2
+ import { normalizeWorkspacePath } from "./path.js";
3
+ /** Read-only adapter for input[type=file][webkitdirectory] and drag/drop files. */
4
+ export class FileListWorkspaceSource {
5
+ writable = false;
6
+ #files = new Map();
7
+ constructor(files, options = {}) {
8
+ const ignoredNames = new Set([
9
+ ...DEFAULT_IGNORED_WORKSPACE_NAMES,
10
+ ...(options.ignoredNames ?? []),
11
+ ]);
12
+ const iterable = Symbol.iterator in Object(files)
13
+ ? files
14
+ : Array.from(files);
15
+ const entries = [...iterable].map((file) => ({
16
+ file,
17
+ path: normalizeWorkspacePath(file.webkitRelativePath || file.name),
18
+ }));
19
+ const selectedDirectory = commonSelectedDirectory(entries.map((entry) => entry.path));
20
+ for (const { file, path } of entries) {
21
+ const relativePath = file.webkitRelativePath;
22
+ const workspacePath = relativePath && selectedDirectory
23
+ ? path.slice(selectedDirectory.length + 1)
24
+ : path;
25
+ if (isIgnoredWorkspacePath(workspacePath, ignoredNames))
26
+ continue;
27
+ this.#files.set(workspacePath, file);
28
+ }
29
+ }
30
+ async list(prefix = "") {
31
+ const normalizedPrefix = prefix ? normalizeWorkspacePath(prefix) : "";
32
+ return [...this.#files.entries()]
33
+ .filter(([path]) => !normalizedPrefix ||
34
+ path === normalizedPrefix ||
35
+ path.startsWith(`${normalizedPrefix}/`))
36
+ .map(([path, file]) => ({
37
+ path,
38
+ name: file.name,
39
+ kind: "file",
40
+ size: file.size,
41
+ lastModified: file.lastModified,
42
+ }));
43
+ }
44
+ async has(path) {
45
+ return this.#files.has(normalizeWorkspacePath(path));
46
+ }
47
+ async read(path) {
48
+ const normalized = normalizeWorkspacePath(path);
49
+ const file = this.#files.get(normalized);
50
+ if (!file)
51
+ throw new Error(`Workspace file not found: ${normalized}`);
52
+ return file;
53
+ }
54
+ }
55
+ function commonSelectedDirectory(paths) {
56
+ if (paths.length === 0)
57
+ return null;
58
+ const first = paths[0]?.split("/")[0];
59
+ if (!first || paths.some((path) => !path.startsWith(`${first}/`))) {
60
+ return null;
61
+ }
62
+ return first;
63
+ }
64
+ //# sourceMappingURL=file-list-source.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-list-source.js","sourceRoot":"","sources":["../src/file-list-source.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export * from "./directory-source.js";
2
+ export * from "./file-list-source.js";
3
+ export * from "./memory-source.js";
4
+ export * from "./path.js";
5
+ export * from "./workspace-session.js";
6
+ export * from "./workspace-index.js";
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,QAAQ,CAAC;AACvB,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,7 @@
1
+ export * from "./directory-source.js";
2
+ export * from "./file-list-source.js";
3
+ export * from "./memory-source.js";
4
+ export * from "./path.js";
5
+ export * from "./workspace-session.js";
6
+ export * from "./workspace-index.js";
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,QAAQ,CAAC;AACvB,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC"}
@@ -0,0 +1,13 @@
1
+ import type { WorkspaceEntry, WorkspaceSource } from "./directory-source.js";
2
+ export declare class MemoryWorkspaceSource implements WorkspaceSource {
3
+ #private;
4
+ readonly writable = true;
5
+ constructor(files?: Readonly<Record<string, Blob | string>>);
6
+ list(prefix?: string): Promise<readonly WorkspaceEntry[]>;
7
+ has(path: string): Promise<boolean>;
8
+ read(path: string): Promise<File>;
9
+ write(path: string, data: Blob | string): Promise<void>;
10
+ writeAtomic(path: string, data: Blob | string): Promise<void>;
11
+ remove(path: string): Promise<void>;
12
+ }
13
+ //# sourceMappingURL=memory-source.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-source.d.ts","sourceRoot":"","sources":["../src/memory-source.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAG1E,qBAAa,qBAAsB,YAAW,eAAe;;IAC3D,QAAQ,CAAC,QAAQ,QAAQ;gBAGb,KAAK,GAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,GAAG,MAAM,CAAC,CAAM;IAOzD,IAAI,CAAC,MAAM,SAAK,GAAG,OAAO,CAAC,SAAS,cAAc,EAAE,CAAC;IAarD,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAInC,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOjC,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,GAAG,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKvD,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,GAAG,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI7D,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAG1C"}
@@ -0,0 +1,51 @@
1
+ import { normalizeWorkspacePath } from "./path.js";
2
+ export class MemoryWorkspaceSource {
3
+ writable = true;
4
+ #files = new Map();
5
+ constructor(files = {}) {
6
+ for (const [path, data] of Object.entries(files)) {
7
+ const normalized = normalizeWorkspacePath(path);
8
+ this.#files.set(normalized, toFile(normalized, data));
9
+ }
10
+ }
11
+ async list(prefix = "") {
12
+ const normalized = prefix ? normalizeWorkspacePath(prefix) : "";
13
+ return [...this.#files.entries()]
14
+ .filter(([path]) => !normalized || path.startsWith(normalized))
15
+ .map(([path, file]) => ({
16
+ path,
17
+ name: file.name,
18
+ kind: "file",
19
+ size: file.size,
20
+ lastModified: file.lastModified,
21
+ }));
22
+ }
23
+ async has(path) {
24
+ return this.#files.has(normalizeWorkspacePath(path));
25
+ }
26
+ async read(path) {
27
+ const normalized = normalizeWorkspacePath(path);
28
+ const file = this.#files.get(normalized);
29
+ if (!file)
30
+ throw new Error(`Workspace file not found: ${normalized}`);
31
+ return file;
32
+ }
33
+ async write(path, data) {
34
+ const normalized = normalizeWorkspacePath(path);
35
+ this.#files.set(normalized, toFile(normalized, data));
36
+ }
37
+ async writeAtomic(path, data) {
38
+ await this.write(path, data);
39
+ }
40
+ async remove(path) {
41
+ this.#files.delete(normalizeWorkspacePath(path));
42
+ }
43
+ }
44
+ function toFile(path, data) {
45
+ const name = path.split("/").at(-1) ?? path;
46
+ return new File([data], name, {
47
+ type: data instanceof Blob ? data.type : "text/plain",
48
+ lastModified: Date.now(),
49
+ });
50
+ }
51
+ //# sourceMappingURL=memory-source.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-source.js","sourceRoot":"","sources":["../src/memory-source.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,sBAAsB,EAAE,MAAM,QAAQ,CAAC;AAEhD,MAAM,OAAO,qBAAqB;IACvB,QAAQ,GAAG,IAAI,CAAC;IAChB,MAAM,GAAG,IAAI,GAAG,EAAgB,CAAC;IAE1C,YAAY,QAAiD,EAAE;QAC7D,KAAK,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACjD,MAAM,UAAU,GAAG,sBAAsB,CAAC,IAAI,CAAC,CAAC;YAChD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE,MAAM,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC,CAAC;QACxD,CAAC;IACH,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,EAAE;QACpB,MAAM,UAAU,GAAG,MAAM,CAAC,CAAC,CAAC,sBAAsB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAChE,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;aAC9B,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,UAAU,IAAI,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;aAC9D,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;YACtB,IAAI;YACJ,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,IAAI,EAAE,MAAe;YACrB,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,YAAY,EAAE,IAAI,CAAC,YAAY;SAChC,CAAC,CAAC,CAAC;IACR,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,IAAY;QACpB,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,sBAAsB,CAAC,IAAI,CAAC,CAAC,CAAC;IACvD,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,IAAY;QACrB,MAAM,UAAU,GAAG,sBAAsB,CAAC,IAAI,CAAC,CAAC;QAChD,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QACzC,IAAI,CAAC,IAAI;YAAE,MAAM,IAAI,KAAK,CAAC,6BAA6B,UAAU,EAAE,CAAC,CAAC;QACtE,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,IAAY,EAAE,IAAmB;QAC3C,MAAM,UAAU,GAAG,sBAAsB,CAAC,IAAI,CAAC,CAAC;QAChD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE,MAAM,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC,CAAC;IACxD,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,IAAY,EAAE,IAAmB;QACjD,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC/B,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,IAAY;QACvB,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,sBAAsB,CAAC,IAAI,CAAC,CAAC,CAAC;IACnD,CAAC;CACF;AAED,SAAS,MAAM,CAAC,IAAY,EAAE,IAAmB;IAC/C,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;IAC5C,OAAO,IAAI,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE;QAC5B,IAAI,EAAE,IAAI,YAAY,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,YAAY;QACrD,YAAY,EAAE,IAAI,CAAC,GAAG,EAAE;KACzB,CAAC,CAAC;AACL,CAAC"}
package/dist/path.d.ts ADDED
@@ -0,0 +1,4 @@
1
+ export declare function normalizeWorkspacePath(path: string): string;
2
+ export declare function dirname(path: string): string;
3
+ export declare function resolveWorkspaceRelativePath(fromFilePath: string, relativePath: string): string;
4
+ //# sourceMappingURL=path.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"path.d.ts","sourceRoot":"","sources":["../src/path.ts"],"names":[],"mappings":"AAEA,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAoB3D;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAI5C;AAED,wBAAgB,4BAA4B,CAC1C,YAAY,EAAE,MAAM,EACpB,YAAY,EAAE,MAAM,GACnB,MAAM,CA4BR"}
package/dist/path.js ADDED
@@ -0,0 +1,51 @@
1
+ const NETWORK_SCHEME = /^[a-z][a-z\d+.-]*:/i;
2
+ export function normalizeWorkspacePath(path) {
3
+ const normalized = path.replaceAll("\\", "/").replace(/^\.\//, "");
4
+ if (!normalized ||
5
+ normalized.startsWith("/") ||
6
+ normalized.includes("\0") ||
7
+ NETWORK_SCHEME.test(normalized)) {
8
+ throw new Error(`Workspace paths must be relative: ${path}`);
9
+ }
10
+ const segments = normalized
11
+ .split("/")
12
+ .filter((segment) => Boolean(segment) && segment !== ".");
13
+ if (segments.length === 0) {
14
+ throw new Error(`Workspace paths must be relative: ${path}`);
15
+ }
16
+ if (segments.some((segment) => segment === "..")) {
17
+ throw new Error(`Workspace path escapes the selected directory: ${path}`);
18
+ }
19
+ return segments.join("/");
20
+ }
21
+ export function dirname(path) {
22
+ const normalized = normalizeWorkspacePath(path);
23
+ const index = normalized.lastIndexOf("/");
24
+ return index < 0 ? "" : normalized.slice(0, index);
25
+ }
26
+ export function resolveWorkspaceRelativePath(fromFilePath, relativePath) {
27
+ const normalizedFrom = normalizeWorkspacePath(fromFilePath);
28
+ const normalizedRelative = relativePath.replaceAll("\\", "/");
29
+ if (!normalizedRelative ||
30
+ normalizedRelative.startsWith("/") ||
31
+ normalizedRelative.includes("\0") ||
32
+ NETWORK_SCHEME.test(normalizedRelative)) {
33
+ throw new Error(`Workspace reference must be a local relative path: ${relativePath}`);
34
+ }
35
+ const segments = dirname(normalizedFrom).split("/").filter(Boolean);
36
+ for (const segment of normalizedRelative.split("/")) {
37
+ if (!segment || segment === ".")
38
+ continue;
39
+ if (segment === "..") {
40
+ if (segments.length === 0) {
41
+ throw new Error(`Workspace reference escapes the selected directory: ${relativePath}`);
42
+ }
43
+ segments.pop();
44
+ }
45
+ else {
46
+ segments.push(segment);
47
+ }
48
+ }
49
+ return normalizeWorkspacePath(segments.join("/"));
50
+ }
51
+ //# sourceMappingURL=path.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"path.js","sourceRoot":"","sources":["../src/path.ts"],"names":[],"mappings":"AAAA,MAAM,cAAc,GAAG,qBAAqB,CAAC;AAE7C,MAAM,UAAU,sBAAsB,CAAC,IAAY;IACjD,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IACnE,IACE,CAAC,UAAU;QACX,UAAU,CAAC,UAAU,CAAC,GAAG,CAAC;QAC1B,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC;QACzB,cAAc,CAAC,IAAI,CAAC,UAAU,CAAC,EAC/B,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,qCAAqC,IAAI,EAAE,CAAC,CAAC;IAC/D,CAAC;IACD,MAAM,QAAQ,GAAG,UAAU;SACxB,KAAK,CAAC,GAAG,CAAC;SACV,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,OAAO,KAAK,GAAG,CAAC,CAAC;IAC5D,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,qCAAqC,IAAI,EAAE,CAAC,CAAC;IAC/D,CAAC;IACD,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,KAAK,IAAI,CAAC,EAAE,CAAC;QACjD,MAAM,IAAI,KAAK,CAAC,kDAAkD,IAAI,EAAE,CAAC,CAAC;IAC5E,CAAC;IACD,OAAO,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC5B,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,IAAY;IAClC,MAAM,UAAU,GAAG,sBAAsB,CAAC,IAAI,CAAC,CAAC;IAChD,MAAM,KAAK,GAAG,UAAU,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IAC1C,OAAO,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;AACrD,CAAC;AAED,MAAM,UAAU,4BAA4B,CAC1C,YAAoB,EACpB,YAAoB;IAEpB,MAAM,cAAc,GAAG,sBAAsB,CAAC,YAAY,CAAC,CAAC;IAC5D,MAAM,kBAAkB,GAAG,YAAY,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IAC9D,IACE,CAAC,kBAAkB;QACnB,kBAAkB,CAAC,UAAU,CAAC,GAAG,CAAC;QAClC,kBAAkB,CAAC,QAAQ,CAAC,IAAI,CAAC;QACjC,cAAc,CAAC,IAAI,CAAC,kBAAkB,CAAC,EACvC,CAAC;QACD,MAAM,IAAI,KAAK,CACb,sDAAsD,YAAY,EAAE,CACrE,CAAC;IACJ,CAAC;IACD,MAAM,QAAQ,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACpE,KAAK,MAAM,OAAO,IAAI,kBAAkB,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;QACpD,IAAI,CAAC,OAAO,IAAI,OAAO,KAAK,GAAG;YAAE,SAAS;QAC1C,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;YACrB,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC1B,MAAM,IAAI,KAAK,CACb,uDAAuD,YAAY,EAAE,CACtE,CAAC;YACJ,CAAC;YACD,QAAQ,CAAC,GAAG,EAAE,CAAC;QACjB,CAAC;aAAM,CAAC;YACN,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACzB,CAAC;IACH,CAAC;IACD,OAAO,sBAAsB,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AACpD,CAAC"}
@@ -0,0 +1,23 @@
1
+ import type { AssetReference } from "@skenora/contracts";
2
+ import type { WorkspaceEntry } from "./directory-source.js";
3
+ export interface WorkspaceEntryChange {
4
+ before: WorkspaceEntry;
5
+ after: WorkspaceEntry;
6
+ }
7
+ export interface WorkspaceDiff {
8
+ added: readonly WorkspaceEntry[];
9
+ changed: readonly WorkspaceEntryChange[];
10
+ missing: readonly WorkspaceEntry[];
11
+ }
12
+ export declare class WorkspaceIndex {
13
+ #private;
14
+ constructor(entries: readonly WorkspaceEntry[]);
15
+ get entries(): readonly WorkspaceEntry[];
16
+ get(path: string): WorkspaceEntry | undefined;
17
+ files(extension?: string): readonly WorkspaceEntry[];
18
+ sceneDocuments(): readonly WorkspaceEntry[];
19
+ assets(): readonly AssetReference[];
20
+ diff(nextEntries: readonly WorkspaceEntry[]): WorkspaceDiff;
21
+ }
22
+ export declare function inferAssetKind(path: string): AssetReference["kind"] | null;
23
+ //# sourceMappingURL=workspace-index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace-index.d.ts","sourceRoot":"","sources":["../src/workspace-index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAGzD,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,cAAc,CAAC;IACvB,KAAK,EAAE,cAAc,CAAC;CACvB;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,SAAS,cAAc,EAAE,CAAC;IACjC,OAAO,EAAE,SAAS,oBAAoB,EAAE,CAAC;IACzC,OAAO,EAAE,SAAS,cAAc,EAAE,CAAC;CACpC;AAED,qBAAa,cAAc;;gBAIb,OAAO,EAAE,SAAS,cAAc,EAAE;IAO9C,IAAI,OAAO,IAAI,SAAS,cAAc,EAAE,CAEvC;IAED,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS;IAI7C,KAAK,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,cAAc,EAAE;IASpD,cAAc,IAAI,SAAS,cAAc,EAAE;IAS3C,MAAM,IAAI,SAAS,cAAc,EAAE;IAsBnC,IAAI,CAAC,WAAW,EAAE,SAAS,cAAc,EAAE,GAAG,aAAa;CAa5D;AAUD,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,CAAC,MAAM,CAAC,GAAG,IAAI,CAgB1E"}
@@ -0,0 +1,87 @@
1
+ import { normalizeWorkspacePath } from "./path.js";
2
+ export class WorkspaceIndex {
3
+ #entries;
4
+ #byPath;
5
+ constructor(entries) {
6
+ this.#entries = [...entries].sort((left, right) => left.path.localeCompare(right.path));
7
+ this.#byPath = new Map(this.#entries.map((entry) => [entry.path, entry]));
8
+ }
9
+ get entries() {
10
+ return this.#entries;
11
+ }
12
+ get(path) {
13
+ return this.#byPath.get(normalizeWorkspacePath(path));
14
+ }
15
+ files(extension) {
16
+ const normalized = extension?.replace(/^\./, "").toLowerCase();
17
+ return this.#entries.filter((entry) => entry.kind === "file" &&
18
+ (!normalized || entry.path.toLowerCase().endsWith(`.${normalized}`)));
19
+ }
20
+ sceneDocuments() {
21
+ return this.#entries.filter((entry) => entry.kind === "file" &&
22
+ entry.path.toLowerCase().endsWith(".scene.json") &&
23
+ !entry.path.startsWith(".skenora/checkpoints/"));
24
+ }
25
+ assets() {
26
+ return this.files().flatMap((entry) => {
27
+ if (entry.path === ".skenora/workspace.json" ||
28
+ entry.path.toLowerCase().endsWith(".scene.json")) {
29
+ return [];
30
+ }
31
+ const kind = inferAssetKind(entry.path);
32
+ if (!kind)
33
+ return [];
34
+ return [
35
+ {
36
+ id: stableAssetId(entry.path),
37
+ uri: entry.path,
38
+ source: { type: "workspace", path: entry.path },
39
+ kind,
40
+ label: entry.name,
41
+ },
42
+ ];
43
+ });
44
+ }
45
+ diff(nextEntries) {
46
+ const next = new WorkspaceIndex(nextEntries);
47
+ const added = next.entries.filter((entry) => !this.#byPath.has(entry.path));
48
+ const missing = this.#entries.filter((entry) => !next.#byPath.has(entry.path));
49
+ const changed = next.entries.flatMap((after) => {
50
+ const before = this.#byPath.get(after.path);
51
+ if (!before || entriesEqual(before, after))
52
+ return [];
53
+ return [{ before, after }];
54
+ });
55
+ return { added, changed, missing };
56
+ }
57
+ }
58
+ function entriesEqual(left, right) {
59
+ return (left.kind === right.kind &&
60
+ left.size === right.size &&
61
+ left.lastModified === right.lastModified);
62
+ }
63
+ export function inferAssetKind(path) {
64
+ const extension = path.split(".").at(-1)?.toLowerCase();
65
+ if (["glb", "gltf"].includes(extension ?? ""))
66
+ return "model";
67
+ if (["png", "jpg", "jpeg", "webp", "avif", "ktx2", "tga"].includes(extension ?? "")) {
68
+ return "texture";
69
+ }
70
+ if (["env", "dds", "hdr", "exr"].includes(extension ?? "")) {
71
+ return "environment";
72
+ }
73
+ if (["mp3", "wav", "ogg", "m4a"].includes(extension ?? ""))
74
+ return "audio";
75
+ if (["json", "csv"].includes(extension ?? ""))
76
+ return "data";
77
+ return null;
78
+ }
79
+ function stableAssetId(path) {
80
+ let hash = 2_166_136_261;
81
+ for (const character of path) {
82
+ hash ^= character.charCodeAt(0);
83
+ hash = Math.imul(hash, 16_777_619);
84
+ }
85
+ return `asset-${(hash >>> 0).toString(16).padStart(8, "0")}`;
86
+ }
87
+ //# sourceMappingURL=workspace-index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace-index.js","sourceRoot":"","sources":["../src/workspace-index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,92 @@
1
+ import { type SceneDocumentData } from "@skenora/contracts";
2
+ import { EventHub } from "@skenora/events";
3
+ import type { WorkspaceEntry, WorkspaceSource } from "./directory-source.js";
4
+ import { WorkspaceIndex, type WorkspaceDiff } from "./workspace-index.js";
5
+ export declare const SKENORA_WORKSPACE_DIRECTORY = ".skenora";
6
+ export declare const SKENORA_SCENES_DIRECTORY = ".skenora/scenes";
7
+ export declare const SKENORA_CHECKPOINTS_DIRECTORY = ".skenora/checkpoints";
8
+ export declare const DEFAULT_SCENE_FILE = ".skenora/scenes/main.scene.json";
9
+ export declare const LEGACY_SCENE_FILE = "skenora.scene.json";
10
+ export declare const WORKSPACE_MANIFEST_FILE = ".skenora/workspace.json";
11
+ export interface WorkspaceEventMap {
12
+ "workspace.scanned": {
13
+ entries: readonly WorkspaceEntry[];
14
+ };
15
+ "workspace.refreshed": {
16
+ diff: WorkspaceDiff;
17
+ };
18
+ "workspace.document.loaded": {
19
+ path: string;
20
+ document: SceneDocumentData;
21
+ };
22
+ "workspace.document.saved": {
23
+ path: string;
24
+ };
25
+ "workspace.document.checkpointed": {
26
+ path: string;
27
+ sourcePath: string | null;
28
+ };
29
+ "workspace.document.checkpoint.loaded": {
30
+ path: string;
31
+ document: SceneDocumentData;
32
+ };
33
+ "workspace.document.restored": {
34
+ checkpointPath: string;
35
+ targetPath: string;
36
+ };
37
+ "workspace.files.imported": {
38
+ paths: readonly string[];
39
+ };
40
+ }
41
+ export interface WorkspaceSessionOptions {
42
+ events?: EventHub<WorkspaceEventMap>;
43
+ }
44
+ export interface SaveDocumentOptions {
45
+ checkpoint?: boolean;
46
+ overwrite?: boolean;
47
+ }
48
+ export interface ImportFilesOptions {
49
+ targetDirectory?: string;
50
+ conflict?: "error" | "replace" | "rename";
51
+ }
52
+ export interface WorkspaceImportItem {
53
+ file: File;
54
+ /** Path inside the imported bundle. Defaults to file.name. */
55
+ relativePath?: string;
56
+ }
57
+ export type WorkspaceImportInput = File | WorkspaceImportItem;
58
+ export interface ImportFilesResult {
59
+ paths: readonly string[];
60
+ diff: WorkspaceDiff;
61
+ }
62
+ export interface ImportModelBundleOptions extends Omit<ImportFilesOptions, "conflict"> {
63
+ conflict?: "error" | "replace";
64
+ }
65
+ export interface ImportModelBundleResult extends ImportFilesResult {
66
+ primaryPath: string;
67
+ }
68
+ export declare class WorkspaceConflictError extends Error {
69
+ readonly path: string;
70
+ constructor(path: string, message?: string);
71
+ }
72
+ export declare class WorkspaceSession {
73
+ #private;
74
+ readonly source: WorkspaceSource;
75
+ readonly events: EventHub<WorkspaceEventMap>;
76
+ constructor(source: WorkspaceSource, options?: WorkspaceSessionOptions);
77
+ get index(): WorkspaceIndex;
78
+ get documentPath(): string | null;
79
+ scan(): Promise<readonly WorkspaceEntry[]>;
80
+ discoverSceneDocuments(): Promise<readonly WorkspaceEntry[]>;
81
+ refresh(): Promise<WorkspaceDiff>;
82
+ loadDocument(path?: string): Promise<SceneDocumentData>;
83
+ saveDocument(document: SceneDocumentData, path?: string, options?: SaveDocumentOptions): Promise<void>;
84
+ checkpointDocument(document: SceneDocumentData, sourcePath?: string | null): Promise<string>;
85
+ listCheckpoints(documentId?: string): Promise<readonly WorkspaceEntry[]>;
86
+ loadCheckpoint(path: string): Promise<SceneDocumentData>;
87
+ restoreCheckpoint(checkpoint: string, targetPath?: string): Promise<void>;
88
+ importFiles(files: Iterable<WorkspaceImportInput>, options?: ImportFilesOptions): Promise<ImportFilesResult>;
89
+ importModelBundle(primary: WorkspaceImportInput, dependencies?: Iterable<WorkspaceImportInput>, options?: ImportModelBundleOptions): Promise<ImportModelBundleResult>;
90
+ dispose(): void;
91
+ }
92
+ //# sourceMappingURL=workspace-session.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace-session.d.ts","sourceRoot":"","sources":["../src/workspace-session.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,461 @@
1
+ import { assertSceneDocument, parseSceneDocument, serializeSceneDocument, } from "@skenora/contracts";
2
+ import { EventHub } from "@skenora/events";
3
+ import { dirname, normalizeWorkspacePath, resolveWorkspaceRelativePath, } from "./path.js";
4
+ import { WorkspaceIndex } from "./workspace-index.js";
5
+ export const SKENORA_WORKSPACE_DIRECTORY = ".skenora";
6
+ export const SKENORA_SCENES_DIRECTORY = ".skenora/scenes";
7
+ export const SKENORA_CHECKPOINTS_DIRECTORY = ".skenora/checkpoints";
8
+ export const DEFAULT_SCENE_FILE = ".skenora/scenes/main.scene.json";
9
+ export const LEGACY_SCENE_FILE = "skenora.scene.json";
10
+ export const WORKSPACE_MANIFEST_FILE = ".skenora/workspace.json";
11
+ export class WorkspaceConflictError extends Error {
12
+ path;
13
+ constructor(path, message = `Workspace file changed: ${path}`) {
14
+ super(message);
15
+ this.name = "WorkspaceConflictError";
16
+ this.path = path;
17
+ }
18
+ }
19
+ export class WorkspaceSession {
20
+ source;
21
+ events;
22
+ #ownsEvents;
23
+ #documentStamps = new Map();
24
+ #index = new WorkspaceIndex([]);
25
+ #documentPath = null;
26
+ #disposed = false;
27
+ constructor(source, options = {}) {
28
+ this.source = source;
29
+ this.events = options.events ?? new EventHub();
30
+ this.#ownsEvents = options.events === undefined;
31
+ }
32
+ get index() {
33
+ return this.#index;
34
+ }
35
+ get documentPath() {
36
+ return this.#documentPath;
37
+ }
38
+ async scan() {
39
+ this.#assertActive();
40
+ const entries = await this.source.list();
41
+ this.#index = new WorkspaceIndex(entries);
42
+ this.events.publish("workspace.scanned", { entries }, { source: "workspace" });
43
+ return entries;
44
+ }
45
+ async discoverSceneDocuments() {
46
+ this.#assertActive();
47
+ if (this.#index.entries.length === 0)
48
+ await this.scan();
49
+ return this.#index.sceneDocuments();
50
+ }
51
+ async refresh() {
52
+ this.#assertActive();
53
+ const entries = await this.source.list();
54
+ const diff = this.#index.diff(entries);
55
+ this.#index = new WorkspaceIndex(entries);
56
+ this.events.publish("workspace.refreshed", { diff }, { source: "workspace" });
57
+ return diff;
58
+ }
59
+ async loadDocument(path) {
60
+ this.#assertActive();
61
+ const normalized = normalizeWorkspacePath(path ?? (await this.#findDefaultScenePath()));
62
+ const file = await this.source.read(normalized);
63
+ const document = parseSceneDocument(await file.text());
64
+ this.#documentStamps.set(normalized, await stampFile(file));
65
+ this.#documentPath = normalized;
66
+ this.events.publish("workspace.document.loaded", { path: normalized, document }, { source: "workspace" });
67
+ return document;
68
+ }
69
+ async saveDocument(document, path, options = {}) {
70
+ this.#assertActive();
71
+ this.#assertWritable();
72
+ const normalized = normalizeWorkspacePath(path ?? this.#documentPath ?? DEFAULT_SCENE_FILE);
73
+ assertSceneDocument(document);
74
+ const existing = await this.#readExisting(normalized);
75
+ if (existing && !options.overwrite) {
76
+ const expected = this.#documentStamps.get(normalized);
77
+ if (!expected || !stampsEqual(expected, await stampFile(existing))) {
78
+ throw new WorkspaceConflictError(normalized);
79
+ }
80
+ }
81
+ if (existing && (options.checkpoint ?? true)) {
82
+ await this.#writeCheckpoint(existing, document.id, normalized);
83
+ }
84
+ await this.#write(normalized, serializeSceneDocument(document));
85
+ const saved = await this.source.read(normalized);
86
+ this.#documentStamps.set(normalized, await stampFile(saved));
87
+ this.#documentPath = normalized;
88
+ const manifest = {
89
+ schema: "skenora.workspace",
90
+ version: 1,
91
+ recentScene: normalized,
92
+ };
93
+ await this.#write(WORKSPACE_MANIFEST_FILE, JSON.stringify(manifest, null, 2));
94
+ await this.refresh();
95
+ this.events.publish("workspace.document.saved", { path: normalized }, { source: "workspace" });
96
+ }
97
+ async checkpointDocument(document, sourcePath = null) {
98
+ this.#assertActive();
99
+ this.#assertWritable();
100
+ assertSceneDocument(document);
101
+ const path = await this.#availableCheckpointPath(document.id);
102
+ await this.#write(path, serializeSceneDocument(document));
103
+ await this.refresh();
104
+ this.events.publish("workspace.document.checkpointed", { path, sourcePath }, { source: "workspace" });
105
+ return path;
106
+ }
107
+ async listCheckpoints(documentId) {
108
+ this.#assertActive();
109
+ if (this.#index.entries.length === 0)
110
+ await this.scan();
111
+ const prefix = documentId ? `${safeDocumentId(documentId)}-` : null;
112
+ return this.#index.entries
113
+ .filter((entry) => entry.kind === "file" &&
114
+ entry.path.startsWith(`${SKENORA_CHECKPOINTS_DIRECTORY}/`) &&
115
+ entry.path.endsWith(".scene.json") &&
116
+ (!prefix || entry.name.startsWith(prefix)))
117
+ .sort((left, right) => (right.lastModified ?? 0) - (left.lastModified ?? 0) ||
118
+ right.path.localeCompare(left.path));
119
+ }
120
+ async loadCheckpoint(path) {
121
+ this.#assertActive();
122
+ const normalized = assertCheckpointPath(path);
123
+ const file = await this.source.read(normalized);
124
+ const document = parseSceneDocument(await file.text());
125
+ this.events.publish("workspace.document.checkpoint.loaded", { path: normalized, document }, { source: "workspace" });
126
+ return document;
127
+ }
128
+ async restoreCheckpoint(checkpoint, targetPath) {
129
+ this.#assertActive();
130
+ const checkpointPath = assertCheckpointPath(checkpoint);
131
+ const document = await this.loadCheckpoint(checkpointPath);
132
+ const target = normalizeWorkspacePath(targetPath ?? this.#documentPath ?? DEFAULT_SCENE_FILE);
133
+ await this.saveDocument(document, target);
134
+ this.events.publish("workspace.document.restored", { checkpointPath, targetPath: target }, { source: "workspace" });
135
+ }
136
+ async importFiles(files, options = {}) {
137
+ this.#assertActive();
138
+ this.#assertWritable();
139
+ const targetDirectory = normalizeWorkspacePath(options.targetDirectory ?? ".skenora/imports");
140
+ const inputs = [...files];
141
+ if (inputs.length === 0) {
142
+ throw new Error("Workspace import requires at least one file");
143
+ }
144
+ const planned = [];
145
+ const reserved = new Set();
146
+ for (const input of inputs) {
147
+ const { file, relativePath } = normalizeImportInput(input);
148
+ let path = normalizeWorkspacePath(`${targetDirectory}/${relativePath}`);
149
+ const collides = reserved.has(path) || (await this.source.has(path));
150
+ if (collides) {
151
+ if ((options.conflict ?? "error") === "error") {
152
+ throw new WorkspaceConflictError(path, `Workspace import already exists: ${path}`);
153
+ }
154
+ if (options.conflict === "rename") {
155
+ path = await this.#availableImportPath(path, reserved);
156
+ }
157
+ else if (reserved.has(path)) {
158
+ throw new WorkspaceConflictError(path, `Import batch contains duplicate target paths: ${path}`);
159
+ }
160
+ }
161
+ reserved.add(path);
162
+ if (path === WORKSPACE_MANIFEST_FILE) {
163
+ throw new Error("Workspace imports cannot replace workspace.json");
164
+ }
165
+ const previous = (await this.source.has(path))
166
+ ? await this.source.read(path)
167
+ : null;
168
+ planned.push({
169
+ file,
170
+ path,
171
+ previous,
172
+ });
173
+ }
174
+ if (planned.some((item) => !item.previous) && !this.source.remove) {
175
+ throw new Error("Workspace source cannot roll back an incomplete import");
176
+ }
177
+ const written = [];
178
+ try {
179
+ for (const item of planned) {
180
+ await this.#write(item.path, item.file);
181
+ written.push(item);
182
+ }
183
+ }
184
+ catch (error) {
185
+ const rollbackErrors = [];
186
+ for (const item of written.reverse()) {
187
+ try {
188
+ if (item.previous)
189
+ await this.#write(item.path, item.previous);
190
+ else
191
+ await this.source.remove?.(item.path);
192
+ }
193
+ catch (rollbackError) {
194
+ rollbackErrors.push(rollbackError);
195
+ }
196
+ }
197
+ if (rollbackErrors.length > 0) {
198
+ throw new AggregateError([error, ...rollbackErrors], "Workspace import failed and could not be fully rolled back");
199
+ }
200
+ throw error;
201
+ }
202
+ const imported = planned.map((item) => item.path);
203
+ const diff = await this.refresh();
204
+ this.events.publish("workspace.files.imported", { paths: imported }, { source: "workspace" });
205
+ return { paths: imported, diff };
206
+ }
207
+ async importModelBundle(primary, dependencies = [], options = {}) {
208
+ this.#assertActive();
209
+ this.#assertWritable();
210
+ const primaryItem = normalizeImportInput(primary);
211
+ const primaryExtension = extensionOf(primaryItem.relativePath);
212
+ if (primaryExtension !== ".glb" && primaryExtension !== ".gltf") {
213
+ throw new Error("Model bundle primary file must be GLB or glTF");
214
+ }
215
+ const items = [primaryItem, ...[...dependencies].map(normalizeImportInput)];
216
+ const available = new Set(items.map((item) => item.relativePath));
217
+ if (primaryExtension === ".gltf") {
218
+ const required = await readGltfDependencies(primaryItem.file, primaryItem.relativePath);
219
+ const targetDirectory = normalizeWorkspacePath(options.targetDirectory ?? ".skenora/imports");
220
+ const missing = [];
221
+ for (const relativePath of required) {
222
+ if (available.has(relativePath))
223
+ continue;
224
+ const target = normalizeWorkspacePath(`${targetDirectory}/${relativePath}`);
225
+ if (!(await this.source.has(target)))
226
+ missing.push(relativePath);
227
+ }
228
+ if (missing.length > 0) {
229
+ throw new Error(`glTF import is missing local dependencies: ${missing.join(", ")}`);
230
+ }
231
+ }
232
+ const result = await this.importFiles(items, options);
233
+ const primaryPath = result.paths[0];
234
+ if (!primaryPath)
235
+ throw new Error("Model import did not produce a file");
236
+ return { ...result, primaryPath };
237
+ }
238
+ dispose() {
239
+ if (this.#disposed)
240
+ return;
241
+ this.#disposed = true;
242
+ if (this.#ownsEvents)
243
+ this.events.dispose();
244
+ }
245
+ #assertActive() {
246
+ if (this.#disposed)
247
+ throw new Error("WorkspaceSession has been disposed");
248
+ }
249
+ #assertWritable() {
250
+ if (!this.source.writable || !this.source.write) {
251
+ throw new Error("Workspace is read-only");
252
+ }
253
+ }
254
+ async #findDefaultScenePath() {
255
+ const recentScene = await this.#readRecentScenePath();
256
+ if (recentScene && (await this.source.has(recentScene)))
257
+ return recentScene;
258
+ if (await this.source.has(DEFAULT_SCENE_FILE))
259
+ return DEFAULT_SCENE_FILE;
260
+ if (await this.source.has(LEGACY_SCENE_FILE))
261
+ return LEGACY_SCENE_FILE;
262
+ const scenes = await this.discoverSceneDocuments();
263
+ const first = scenes[0];
264
+ if (!first)
265
+ throw new Error("Workspace contains no scene document");
266
+ return first.path;
267
+ }
268
+ async #readRecentScenePath() {
269
+ if (!(await this.source.has(WORKSPACE_MANIFEST_FILE)))
270
+ return null;
271
+ try {
272
+ const file = await this.source.read(WORKSPACE_MANIFEST_FILE);
273
+ const value = JSON.parse(await file.text());
274
+ if (value.schema !== "skenora.workspace" ||
275
+ value.version !== 1 ||
276
+ typeof value.recentScene !== "string") {
277
+ return null;
278
+ }
279
+ return normalizeWorkspacePath(value.recentScene);
280
+ }
281
+ catch {
282
+ return null;
283
+ }
284
+ }
285
+ async #readExisting(path) {
286
+ return (await this.source.has(path)) ? this.source.read(path) : null;
287
+ }
288
+ async #write(path, data) {
289
+ this.#assertWritable();
290
+ const write = this.source.writeAtomic ?? this.source.write;
291
+ if (!write)
292
+ throw new Error("Workspace is read-only");
293
+ await write.call(this.source, path, data);
294
+ }
295
+ async #writeCheckpoint(file, documentId, sourcePath) {
296
+ const path = await this.#availableCheckpointPath(documentId);
297
+ await this.#write(path, file);
298
+ this.events.publish("workspace.document.checkpointed", { path, sourcePath }, { source: "workspace" });
299
+ }
300
+ async #availableCheckpointPath(documentId) {
301
+ const base = checkpointPath(documentId);
302
+ if (!(await this.source.has(base)))
303
+ return base;
304
+ const extension = ".scene.json";
305
+ const stem = base.slice(0, -extension.length);
306
+ let suffix = 2;
307
+ while (await this.source.has(`${stem}-${suffix}${extension}`)) {
308
+ suffix += 1;
309
+ }
310
+ return `${stem}-${suffix}${extension}`;
311
+ }
312
+ async #availableImportPath(path, reserved) {
313
+ const directory = dirname(path);
314
+ const fileName = path.split("/").at(-1) ?? path;
315
+ const dot = fileName.lastIndexOf(".");
316
+ const base = dot > 0 ? fileName.slice(0, dot) : fileName;
317
+ const extension = dot > 0 ? fileName.slice(dot) : "";
318
+ let suffix = 2;
319
+ while (true) {
320
+ const candidate = normalizeWorkspacePath(`${directory ? `${directory}/` : ""}${base}-${suffix}${extension}`);
321
+ if (!reserved.has(candidate) && !(await this.source.has(candidate))) {
322
+ return candidate;
323
+ }
324
+ suffix += 1;
325
+ }
326
+ }
327
+ }
328
+ async function stampFile(file) {
329
+ const bytes = new Uint8Array(await file.arrayBuffer());
330
+ return {
331
+ size: file.size,
332
+ fingerprint: await fingerprint(bytes),
333
+ };
334
+ }
335
+ function stampsEqual(left, right) {
336
+ return left.size === right.size && left.fingerprint === right.fingerprint;
337
+ }
338
+ function checkpointPath(documentId) {
339
+ const safeId = safeDocumentId(documentId);
340
+ const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
341
+ return `${SKENORA_CHECKPOINTS_DIRECTORY}/${safeId}-${timestamp}.scene.json`;
342
+ }
343
+ function safeDocumentId(documentId) {
344
+ return (documentId.replace(/[^a-z0-9_-]+/gi, "-").replace(/^-+|-+$/g, "") || "scene");
345
+ }
346
+ function assertCheckpointPath(path) {
347
+ const normalized = normalizeWorkspacePath(path);
348
+ if (!normalized.startsWith(`${SKENORA_CHECKPOINTS_DIRECTORY}/`) ||
349
+ !normalized.endsWith(".scene.json")) {
350
+ throw new Error(`Not a Skenora checkpoint path: ${path}`);
351
+ }
352
+ return normalized;
353
+ }
354
+ async function fingerprint(bytes) {
355
+ if (globalThis.crypto?.subtle) {
356
+ const digest = new Uint8Array(await globalThis.crypto.subtle.digest("SHA-256", bytes));
357
+ return [...digest]
358
+ .map((value) => value.toString(16).padStart(2, "0"))
359
+ .join("");
360
+ }
361
+ let hash = 2_166_136_261;
362
+ for (const byte of bytes) {
363
+ hash ^= byte;
364
+ hash = Math.imul(hash, 16_777_619);
365
+ }
366
+ return (hash >>> 0).toString(16).padStart(8, "0");
367
+ }
368
+ function normalizeImportInput(input) {
369
+ if (isWorkspaceImportItem(input)) {
370
+ return {
371
+ file: input.file,
372
+ relativePath: normalizeWorkspacePath(input.relativePath ?? input.file.name),
373
+ };
374
+ }
375
+ return {
376
+ file: input,
377
+ relativePath: normalizeWorkspacePath(input.name),
378
+ };
379
+ }
380
+ function isWorkspaceImportItem(input) {
381
+ return (typeof input === "object" &&
382
+ input !== null &&
383
+ "file" in input &&
384
+ typeof input.file === "object" &&
385
+ input.file !== null);
386
+ }
387
+ async function readGltfDependencies(file, primaryPath) {
388
+ let json;
389
+ try {
390
+ json = JSON.parse(await file.text());
391
+ }
392
+ catch {
393
+ throw new Error(`glTF file is not valid JSON: ${primaryPath}`);
394
+ }
395
+ if (!isRecord(json)) {
396
+ throw new Error(`glTF root must be an object: ${primaryPath}`);
397
+ }
398
+ const dependencies = new Set();
399
+ for (const entry of readGltfArray(json.buffers, "buffers", primaryPath)) {
400
+ if (typeof entry.uri !== "string" || !entry.uri) {
401
+ throw new Error(`glTF buffer is missing a URI: ${primaryPath}`);
402
+ }
403
+ collectGltfDependency(dependencies, primaryPath, entry.uri);
404
+ }
405
+ for (const entry of readGltfArray(json.images, "images", primaryPath)) {
406
+ if (entry.uri === undefined)
407
+ continue;
408
+ if (typeof entry.uri !== "string" || !entry.uri) {
409
+ throw new Error(`glTF image URI is invalid: ${primaryPath}`);
410
+ }
411
+ collectGltfDependency(dependencies, primaryPath, entry.uri);
412
+ }
413
+ return dependencies;
414
+ }
415
+ function readGltfArray(value, name, primaryPath) {
416
+ if (value === undefined)
417
+ return [];
418
+ if (!Array.isArray(value) || value.some((item) => !isRecord(item))) {
419
+ throw new Error(`glTF ${name} must be an array of objects: ${primaryPath}`);
420
+ }
421
+ return value;
422
+ }
423
+ function collectGltfDependency(output, primaryPath, uri) {
424
+ if (/^data:/i.test(uri))
425
+ return;
426
+ output.add(resolveBundlePath(primaryPath, uri));
427
+ }
428
+ function resolveBundlePath(primaryPath, uri) {
429
+ const cleanUri = uri.split(/[?#]/, 1)[0] ?? uri;
430
+ let decoded;
431
+ try {
432
+ decoded = decodeURIComponent(cleanUri);
433
+ }
434
+ catch {
435
+ decoded = cleanUri;
436
+ }
437
+ if (!decoded ||
438
+ decoded.startsWith("/") ||
439
+ /^[a-z][a-z\d+.-]*:/i.test(decoded)) {
440
+ throw new Error(`glTF dependency must be a local relative path: ${uri}`);
441
+ }
442
+ try {
443
+ return resolveWorkspaceRelativePath(primaryPath, decoded);
444
+ }
445
+ catch (error) {
446
+ throw new Error(`Invalid glTF dependency ${uri}: ${errorMessage(error)}`, {
447
+ cause: error,
448
+ });
449
+ }
450
+ }
451
+ function extensionOf(path) {
452
+ const dot = path.lastIndexOf(".");
453
+ return dot < 0 ? "" : path.slice(dot).toLowerCase();
454
+ }
455
+ function isRecord(value) {
456
+ return !!value && typeof value === "object" && !Array.isArray(value);
457
+ }
458
+ function errorMessage(error) {
459
+ return error instanceof Error ? error.message : String(error);
460
+ }
461
+ //# sourceMappingURL=workspace-session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace-session.js","sourceRoot":"","sources":["../src/workspace-session.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,31 @@
1
+ {
2
+ "name": "@skenora/workspace",
3
+ "version": "0.1.2",
4
+ "description": "Local directory, FileList, memory workspace, import, save, and checkpoint support for Skenora.",
5
+ "type": "module",
6
+ "sideEffects": false,
7
+ "files": [
8
+ "dist",
9
+ "README.md"
10
+ ],
11
+ "exports": {
12
+ ".": {
13
+ "types": "./dist/index.d.ts",
14
+ "import": "./dist/index.js",
15
+ "default": "./dist/index.js"
16
+ }
17
+ },
18
+ "publishConfig": {
19
+ "access": "public"
20
+ },
21
+ "dependencies": {
22
+ "@skenora/contracts": "0.1.2",
23
+ "@skenora/events": "0.1.2"
24
+ },
25
+ "scripts": {
26
+ "build": "tsc -p tsconfig.json && node ../../scripts/prepare-package-output.mjs dist",
27
+ "typecheck": "tsc -p tsconfig.json --noEmit"
28
+ },
29
+ "main": "./dist/index.js",
30
+ "types": "./dist/index.d.ts"
31
+ }