@mindcraft-lang/bridge-app 0.1.9 → 0.1.10

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,5 +1,7 @@
1
1
  import type { AppClientMessage, CompileDiagnosticEntry, FileSystemNotification } from "@mindcraft-lang/bridge-protocol";
2
- import type { AppBridgeFeature, DiagnosticEntry, WorkspaceChange, WorkspaceSnapshot } from "./app-bridge.js";
2
+ import type { MindcraftEnvironment } from "@mindcraft-lang/core";
3
+ import { type WorkspaceCompiler as TsWorkspaceCompiler, type WorkspaceCompileResult } from "@mindcraft-lang/ts-compiler";
4
+ import type { AppBridge, AppBridgeFeature, DiagnosticEntry, WorkspaceAdapter, WorkspaceChange, WorkspaceSnapshot } from "./app-bridge.js";
3
5
  export interface DiagnosticSnapshot {
4
6
  files: ReadonlyMap<string, readonly DiagnosticEntry[]>;
5
7
  }
@@ -44,4 +46,24 @@ export declare class CompilationManager {
44
46
  private compileAndEmit;
45
47
  private emitDiagnostics;
46
48
  }
49
+ export type { WorkspaceCompileResult } from "@mindcraft-lang/ts-compiler";
50
+ export interface CreateAppProjectOptions {
51
+ environment: MindcraftEnvironment;
52
+ app: {
53
+ id: string;
54
+ name: string;
55
+ projectId: string;
56
+ projectName: string;
57
+ };
58
+ bridgeUrl: string;
59
+ workspace: WorkspaceAdapter;
60
+ onDidCompile?: (result: WorkspaceCompileResult) => void;
61
+ }
62
+ export interface AppProjectHandle {
63
+ readonly compiler: TsWorkspaceCompiler;
64
+ readonly bridge: AppBridge;
65
+ initialize(): void;
66
+ recreateBridge(bridgeUrl: string): void;
67
+ }
68
+ export declare function createAppProject(options: CreateAppProjectOptions): AppProjectHandle;
47
69
  //# sourceMappingURL=compilation.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"compilation.d.ts","sourceRoot":"","sources":["../src/compilation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AACxH,OAAO,KAAK,EACV,gBAAgB,EAGhB,eAAe,EACf,eAAe,EACf,iBAAiB,EAClB,MAAM,iBAAiB,CAAC;AAEzB,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,eAAe,EAAE,CAAC,CAAC;CACxD;AAED,MAAM,WAAW,iBAAiB;IAChC,gBAAgB,CAAC,QAAQ,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACpD,oBAAoB,CAAC,MAAM,EAAE,eAAe,GAAG,IAAI,CAAC;IACpD,OAAO,IAAI,kBAAkB,CAAC;IAC9B,YAAY,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,kBAAkB,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;CAC5E;AAED,MAAM,WAAW,yBAAyB;IACxC,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,sBAAsB,EAAE,CAAC,CAAC;CAC9C;AAED,MAAM,WAAW,mBAAmB;IAClC,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACjD,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACpD,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,GAAG,IAAI,CAAC;IAC9E,UAAU,IAAI,iBAAiB,CAAC;CACjC;AAwBD,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,yBAAyB,GAAG,gBAAgB,CA8E7F;AAED,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAsB;IAChD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAkC;IACxD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAgB;IAC7C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA6B;IACvD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAqB;IACpD,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAkD;IACxF,OAAO,CAAC,WAAW,CAAgC;IACnD,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAqC;gBAE3D,QAAQ,EAAE,mBAAmB,EAAE,IAAI,EAAE,CAAC,GAAG,EAAE,gBAAgB,KAAK,IAAI,EAAE,WAAW,EAAE,MAAM,OAAO;IAM5G,gBAAgB,CAAC,EAAE,EAAE,sBAAsB,GAAG,IAAI;IAsBlD,aAAa,CAAC,EAAE,EAAE,CAAC,MAAM,EAAE,iBAAiB,KAAK,IAAI,GAAG,MAAM,IAAI;IAOlE,SAAS,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,MAAM,IAAI;IAOjD,eAAe,IAAI,IAAI;IAUvB,OAAO,CAAC,cAAc;IAoCtB,OAAO,CAAC,eAAe;CAyBxB"}
1
+ {"version":3,"file":"compilation.d.ts","sourceRoot":"","sources":["../src/compilation.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,5 @@
1
+ import { createWorkspaceCompiler, } from "@mindcraft-lang/ts-compiler";
2
+ import { createAppBridge } from "./app-bridge.js";
1
3
  function buildFeatureStatus(file, diagnostics) {
2
4
  let errorCount = 0;
3
5
  let warningCount = 0;
@@ -193,3 +195,52 @@ export class CompilationManager {
193
195
  });
194
196
  }
195
197
  }
198
+ export function createAppProject(options) {
199
+ const { environment, workspace } = options;
200
+ const compiler = createWorkspaceCompiler({ environment });
201
+ if (options.onDidCompile) {
202
+ compiler.onDidCompile(options.onDidCompile);
203
+ }
204
+ const augmented = augmentWorkspace(workspace, compiler);
205
+ let currentBridge = buildBridge({ ...options, workspace: augmented }, compiler);
206
+ return {
207
+ compiler,
208
+ get bridge() {
209
+ return currentBridge;
210
+ },
211
+ initialize() {
212
+ compiler.replaceWorkspace(workspace.exportSnapshot());
213
+ compiler.compile();
214
+ },
215
+ recreateBridge(bridgeUrl) {
216
+ currentBridge.stop();
217
+ currentBridge = buildBridge({ ...options, bridgeUrl, workspace: augmented }, compiler);
218
+ },
219
+ };
220
+ }
221
+ function augmentWorkspace(workspace, compiler) {
222
+ return {
223
+ exportSnapshot() {
224
+ const snapshot = workspace.exportSnapshot();
225
+ const controlledFiles = compiler.getCompilerControlledFiles();
226
+ for (const [path, content] of controlledFiles) {
227
+ snapshot.set(path, { kind: "file", content, etag: "compiler-controlled", isReadonly: true });
228
+ }
229
+ return snapshot;
230
+ },
231
+ applyRemoteChange(change) {
232
+ workspace.applyRemoteChange(change);
233
+ },
234
+ onLocalChange(listener) {
235
+ return workspace.onLocalChange(listener);
236
+ },
237
+ };
238
+ }
239
+ function buildBridge(options, compiler) {
240
+ return createAppBridge({
241
+ app: options.app,
242
+ bridgeUrl: options.bridgeUrl,
243
+ workspace: options.workspace,
244
+ features: [createCompilationFeature({ compiler })],
245
+ });
246
+ }
package/dist/index.d.ts CHANGED
@@ -1,3 +1,5 @@
1
1
  export type { AppBridge, AppBridgeFeature, AppBridgeFeatureContext, AppBridgeFeatureStatus, AppBridgeOptions, AppBridgeSnapshot, AppBridgeState, DiagnosticEntry, WorkspaceAdapter, WorkspaceChange, WorkspaceSnapshot, } from "./app-bridge.js";
2
2
  export { createAppBridge } from "./app-bridge.js";
3
+ export type { LocalStorageWorkspaceOptions } from "./local-storage-workspace.js";
4
+ export { createLocalStorageWorkspace } from "./local-storage-workspace.js";
3
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,SAAS,EACT,gBAAgB,EAChB,uBAAuB,EACvB,sBAAsB,EACtB,gBAAgB,EAChB,iBAAiB,EACjB,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,iBAAiB,GAClB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,SAAS,EACT,gBAAgB,EAChB,uBAAuB,EACvB,sBAAsB,EACtB,gBAAgB,EAChB,iBAAiB,EACjB,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,iBAAiB,GAClB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAElD,YAAY,EAAE,4BAA4B,EAAE,MAAM,8BAA8B,CAAC;AACjF,OAAO,EAAE,2BAA2B,EAAE,MAAM,8BAA8B,CAAC"}
package/dist/index.js CHANGED
@@ -1 +1,2 @@
1
1
  export { createAppBridge } from "./app-bridge.js";
2
+ export { createLocalStorageWorkspace } from "./local-storage-workspace.js";
@@ -0,0 +1,8 @@
1
+ import type { WorkspaceAdapter } from "./app-bridge.js";
2
+ export interface LocalStorageWorkspaceOptions {
3
+ storageKey: string;
4
+ debounceMs?: number;
5
+ shouldExclude?: (path: string) => boolean;
6
+ }
7
+ export declare function createLocalStorageWorkspace(options: LocalStorageWorkspaceOptions): WorkspaceAdapter;
8
+ //# sourceMappingURL=local-storage-workspace.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-storage-workspace.d.ts","sourceRoot":"","sources":["../src/local-storage-workspace.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,gBAAgB,EAAsC,MAAM,iBAAiB,CAAC;AAE5F,MAAM,WAAW,4BAA4B;IAC3C,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;CAC3C;AAED,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,4BAA4B,GAAG,gBAAgB,CAEnG"}
@@ -0,0 +1,145 @@
1
+ export function createLocalStorageWorkspace(options) {
2
+ return new LocalStorageWorkspaceStore(options);
3
+ }
4
+ function ensureParentDirectories(snapshot, path) {
5
+ const segments = path.split("/").filter((s) => s.length > 0);
6
+ for (let i = 1; i < segments.length; i++) {
7
+ const dirPath = segments.slice(0, i).join("/");
8
+ if (!snapshot.has(dirPath)) {
9
+ snapshot.set(dirPath, { kind: "directory" });
10
+ }
11
+ }
12
+ }
13
+ function removePath(snapshot, path) {
14
+ snapshot.delete(path);
15
+ const prefix = `${path}/`;
16
+ for (const key of Array.from(snapshot.keys())) {
17
+ if (key.startsWith(prefix)) {
18
+ snapshot.delete(key);
19
+ }
20
+ }
21
+ }
22
+ function filterSnapshot(entries, shouldExclude) {
23
+ const filtered = new Map();
24
+ for (const [path, entry] of entries) {
25
+ if (shouldExclude?.(path)) {
26
+ continue;
27
+ }
28
+ if (entry.kind === "file") {
29
+ ensureParentDirectories(filtered, path);
30
+ }
31
+ filtered.set(path, entry);
32
+ }
33
+ return filtered;
34
+ }
35
+ function applyChange(snapshot, change) {
36
+ switch (change.action) {
37
+ case "write":
38
+ ensureParentDirectories(snapshot, change.path);
39
+ snapshot.set(change.path, {
40
+ kind: "file",
41
+ content: change.content,
42
+ etag: change.newEtag,
43
+ isReadonly: change.isReadonly ?? false,
44
+ });
45
+ break;
46
+ case "delete":
47
+ removePath(snapshot, change.path);
48
+ break;
49
+ case "rename": {
50
+ const entry = snapshot.get(change.oldPath);
51
+ if (!entry) {
52
+ break;
53
+ }
54
+ const descendants = Array.from(snapshot.entries()).filter(([p]) => p.startsWith(`${change.oldPath}/`));
55
+ snapshot.delete(change.oldPath);
56
+ for (const [p] of descendants) {
57
+ snapshot.delete(p);
58
+ }
59
+ ensureParentDirectories(snapshot, change.newPath);
60
+ snapshot.set(change.newPath, entry);
61
+ for (const [p, childEntry] of descendants) {
62
+ snapshot.set(`${change.newPath}${p.slice(change.oldPath.length)}`, childEntry);
63
+ }
64
+ break;
65
+ }
66
+ case "mkdir":
67
+ ensureParentDirectories(snapshot, change.path);
68
+ snapshot.set(change.path, { kind: "directory" });
69
+ break;
70
+ case "rmdir":
71
+ removePath(snapshot, change.path);
72
+ break;
73
+ case "import":
74
+ snapshot.clear();
75
+ for (const [path, entry] of filterSnapshot(change.entries, undefined)) {
76
+ snapshot.set(path, entry);
77
+ }
78
+ break;
79
+ }
80
+ }
81
+ function isChangeExcluded(change, shouldExclude) {
82
+ switch (change.action) {
83
+ case "write":
84
+ case "delete":
85
+ case "mkdir":
86
+ case "rmdir":
87
+ return shouldExclude(change.path);
88
+ case "rename":
89
+ return shouldExclude(change.oldPath) || shouldExclude(change.newPath);
90
+ case "import":
91
+ return false;
92
+ }
93
+ }
94
+ class LocalStorageWorkspaceStore {
95
+ snapshot;
96
+ listeners = new Set();
97
+ storageKey;
98
+ debounceMs;
99
+ shouldExclude;
100
+ persistTimer;
101
+ constructor(options) {
102
+ this.storageKey = options.storageKey;
103
+ this.debounceMs = options.debounceMs ?? 500;
104
+ this.shouldExclude = options.shouldExclude;
105
+ this.snapshot = this.loadSnapshot();
106
+ }
107
+ exportSnapshot() {
108
+ return new Map(this.snapshot);
109
+ }
110
+ applyRemoteChange(change) {
111
+ if (this.shouldExclude && isChangeExcluded(change, this.shouldExclude)) {
112
+ return;
113
+ }
114
+ applyChange(this.snapshot, change);
115
+ this.persist();
116
+ }
117
+ onLocalChange(listener) {
118
+ this.listeners.add(listener);
119
+ return () => {
120
+ this.listeners.delete(listener);
121
+ };
122
+ }
123
+ loadSnapshot() {
124
+ const raw = localStorage.getItem(this.storageKey);
125
+ if (!raw) {
126
+ return new Map();
127
+ }
128
+ try {
129
+ const parsed = JSON.parse(raw);
130
+ return filterSnapshot(parsed, this.shouldExclude);
131
+ }
132
+ catch {
133
+ return new Map();
134
+ }
135
+ }
136
+ persist() {
137
+ if (this.persistTimer !== undefined) {
138
+ window.clearTimeout(this.persistTimer);
139
+ }
140
+ this.persistTimer = window.setTimeout(() => {
141
+ this.persistTimer = undefined;
142
+ localStorage.setItem(this.storageKey, JSON.stringify([...this.snapshot]));
143
+ }, this.debounceMs);
144
+ }
145
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mindcraft-lang/bridge-app",
3
- "version": "0.1.9",
3
+ "version": "0.1.10",
4
4
  "description": "App-side client for the Mindcraft bridge",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -72,8 +72,10 @@
72
72
  "release:major": "node ../../scripts/release.js major"
73
73
  },
74
74
  "dependencies": {
75
- "@mindcraft-lang/bridge-client": "^0.1.9",
76
- "@mindcraft-lang/bridge-protocol": "^0.1.13"
75
+ "@mindcraft-lang/bridge-client": "^0.1.10",
76
+ "@mindcraft-lang/bridge-protocol": "^0.1.14",
77
+ "@mindcraft-lang/core": "^0.1.27",
78
+ "@mindcraft-lang/ts-compiler": "^0.1.19"
77
79
  },
78
80
  "devDependencies": {
79
81
  "@biomejs/biome": "2.3.15",