@aethervtt/shard-platform-tauri 0.1.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -7,5 +7,12 @@ export interface TauriPlatformOptions {
7
7
  * `<appDataDir>/<project>`. Default `<projectRoot>/.shard/user`.
8
8
  */
9
9
  dataDir?: string;
10
+ /** Host-authorized media URL for a project artifact. The host grants its protocol scope first. */
11
+ mediaUrl?: (projectPath: string) => string;
10
12
  }
13
+ /** Host locations for Studio; SDK imports stay behind the platform boundary. */
14
+ export declare function tauriDirectories(): Promise<{
15
+ home: string;
16
+ data: string;
17
+ }>;
11
18
  export declare function createTauriPlatform(options: TauriPlatformOptions): Platform;
package/dist/index.js CHANGED
@@ -1,16 +1,24 @@
1
1
  import { createWebAudioBackend, createWebWorkers } from "@aethervtt/shard-platform-web";
2
+ import { appDataDir, homeDir } from "@tauri-apps/api/path";
2
3
  import {
3
4
  exists,
4
5
  mkdir,
6
+ open,
5
7
  readDir,
6
8
  readFile,
7
9
  readTextFile,
8
10
  remove,
9
11
  rename,
12
+ SeekMode,
13
+ stat,
10
14
  watch,
11
15
  writeFile,
12
16
  writeTextFile
13
17
  } from "@tauri-apps/plugin-fs";
18
+ import { projectFileChanges } from "./watch-events.js";
19
+ async function tauriDirectories() {
20
+ return { home: await homeDir(), data: (await appDataDir()).replace(/\/+$/, "") };
21
+ }
14
22
  function createTauriStorage(dir) {
15
23
  const path = (key) => `${dir}/${key}`;
16
24
  const parent = (p) => p.slice(0, p.lastIndexOf("/"));
@@ -43,20 +51,44 @@ function createTauriStorage(dir) {
43
51
  function createTauriPlatform(options) {
44
52
  const root = options.projectRoot.replace(/\/+$/, "");
45
53
  const resolve = (path) => path.startsWith("/") ? path : `${root}/${path}`;
46
- const relative = (path) => path.startsWith(`${root}/`) ? path.slice(root.length + 1) : path;
47
- const toChange = (event) => {
48
- const type = event.type;
49
- const kind = typeof type === "object" && "create" in type ? "create" : typeof type === "object" && "remove" in type ? "remove" : "modify";
50
- return event.paths.map((path) => ({ kind, path: relative(path) }));
51
- };
52
54
  const fs = {
53
55
  writable: true,
56
+ ...options.mediaUrl ? { resolveUrl: options.mediaUrl } : {},
54
57
  readText: (path) => readTextFile(resolve(path)),
55
58
  readBytes: (path) => readFile(resolve(path)),
59
+ readRange: async (path, offset, length) => {
60
+ const file = await open(resolve(path), { read: true });
61
+ try {
62
+ await file.seek(offset, SeekMode.Start);
63
+ const out = new Uint8Array(length);
64
+ let got = 0;
65
+ while (got < length) {
66
+ const n = await file.read(out.subarray(got));
67
+ if (!n) break;
68
+ got += n;
69
+ }
70
+ return got === length ? out : out.subarray(0, got);
71
+ } finally {
72
+ await file.close();
73
+ }
74
+ },
56
75
  writeText: (path, data) => writeTextFile(resolve(path), data),
57
76
  writeBytes: (path, data) => writeFile(resolve(path), data),
58
77
  exists: (path) => exists(resolve(path)),
59
- watch: async (path, onChange) => watch(resolve(path), (event) => toChange(event).forEach(onChange), {
78
+ remove: async (path) => {
79
+ if (await exists(resolve(path))) await remove(resolve(path));
80
+ },
81
+ stat: async (path) => {
82
+ if (!await exists(resolve(path))) return void 0;
83
+ const info = await stat(resolve(path));
84
+ return { size: info.size, mtime: info.mtime?.getTime() ?? 0 };
85
+ },
86
+ list: async (path) => {
87
+ if (!await exists(resolve(path))) return [];
88
+ const entries = await readDir(resolve(path));
89
+ return entries.filter((entry) => entry.isDirectory || entry.isFile).map((entry) => ({ name: entry.name, kind: entry.isDirectory ? "dir" : "file" }));
90
+ },
91
+ watch: async (path, onChange) => watch(resolve(path), (event) => projectFileChanges(root, event).forEach(onChange), {
60
92
  recursive: true,
61
93
  delayMs: 50
62
94
  })
@@ -84,5 +116,6 @@ function createTauriPlatform(options) {
84
116
  };
85
117
  }
86
118
  export {
87
- createTauriPlatform
119
+ createTauriPlatform,
120
+ tauriDirectories
88
121
  };
@@ -0,0 +1,4 @@
1
+ import type { FileChangeEvent } from '@aethervtt/shard-platform';
2
+ import type { WatchEvent } from '@tauri-apps/plugin-fs';
3
+ /** Reads must never invalidate the source that an observer has just read. */
4
+ export declare function projectFileChanges(root: string, event: WatchEvent): FileChangeEvent[];
@@ -0,0 +1,20 @@
1
+ function projectFileChanges(root, event) {
2
+ const projectRoot = root.replaceAll("\\", "/").replace(/\/+$/, "");
3
+ const type = event.type;
4
+ if (typeof type === "object") {
5
+ if ("access" in type) return [];
6
+ if ("modify" in type && type.modify.kind === "metadata" && type.modify.mode === "access-time")
7
+ return [];
8
+ }
9
+ const kind = typeof type === "object" && "create" in type ? "create" : typeof type === "object" && "remove" in type ? "remove" : "modify";
10
+ return event.paths.map((nativePath) => {
11
+ const path = nativePath.replaceAll("\\", "/");
12
+ return {
13
+ kind,
14
+ path: path.startsWith(`${projectRoot}/`) ? path.slice(projectRoot.length + 1) : path
15
+ };
16
+ });
17
+ }
18
+ export {
19
+ projectFileChanges
20
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aethervtt/shard-platform-tauri",
3
- "version": "0.1.0",
3
+ "version": "0.2.1",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -16,9 +16,9 @@
16
16
  "README.md"
17
17
  ],
18
18
  "dependencies": {
19
- "@aethervtt/shard-core": "0.1.0",
20
- "@aethervtt/shard-platform": "0.1.0",
21
- "@aethervtt/shard-platform-web": "0.1.0",
19
+ "@aethervtt/shard-core": "0.2.1",
20
+ "@aethervtt/shard-platform": "0.2.1",
21
+ "@aethervtt/shard-platform-web": "0.2.1",
22
22
  "@tauri-apps/api": "^2.11.1",
23
23
  "@tauri-apps/plugin-fs": "^2.5.2"
24
24
  },
@@ -32,6 +32,6 @@
32
32
  "provenance": true
33
33
  },
34
34
  "shard": {
35
- "buildSha": "8e14c9896f82a3554b156f1ffdd68f2cc3e7d78a"
35
+ "buildSha": "772eb0d2b8a5fc499105708f4ae92c58788cc9ea"
36
36
  }
37
37
  }