modern-monaco 0.1.0 → 0.1.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/README.md CHANGED
@@ -232,6 +232,26 @@ lazy({
232
232
  > By default, `modern-monaco` uses `react` or `preact` in the `importmap` script as the `jsxImportSource` option for the TypeScript worker.
233
233
  > To use a custom `jsxImportSource` option, add the `@jsxRuntime` specifier in the `importmap` script.
234
234
 
235
+ ### Using Custom FileSystem
236
+
237
+ You can provide a custom filesystem implementation to override the default IndexedDB filesystem.
238
+
239
+ ```ts
240
+ import { lazy, type FileSystem, Workspace } from "modern-monaco";
241
+
242
+ class CustomFileSystem implements FileSystem {
243
+ // Custom FileSystem implementation
244
+ }
245
+
246
+ const workspace = new Workspace({
247
+ initialFiles: {
248
+ "index.html": indexHtml,
249
+ "app.tsx": appTsx,
250
+ },
251
+ customFs: new CustomFileSystem(),
252
+ });
253
+ ```
254
+
235
255
  ## Editor Theme & Language Grammars
236
256
 
237
257
  `modern-monaco` uses [Shiki](https://shiki.style) for syntax highlighting with extensive grammars and themes. By default, it loads themes and grammars from esm.sh on demand.
package/dist/workspace.js CHANGED
@@ -19,64 +19,10 @@ var Workspace = class {
19
19
  _viewState;
20
20
  _entryFile;
21
21
  constructor(options = {}) {
22
- const { name = "default", browserHistory, initialFiles, entryFile } = options;
23
- const db = new WorkspaceDatabase(
24
- name,
25
- {
26
- name: "fs-meta",
27
- keyPath: "url",
28
- onCreate: async (store) => {
29
- if (initialFiles) {
30
- const promises = [];
31
- const now = Date.now();
32
- const reg = { type: 1, version: 1, ctime: now, mtime: now, size: 0 };
33
- const dir = { type: 2, version: 1, ctime: now, mtime: now, size: 0 };
34
- for (const [name2, data] of Object.entries(initialFiles)) {
35
- const { pathname, href: url } = filenameToURL(name2);
36
- let parent = pathname.slice(0, pathname.lastIndexOf("/"));
37
- while (parent) {
38
- promises.push(
39
- promisifyIDBRequest(
40
- store.put({ url: toURL(parent).href, ...dir })
41
- )
42
- );
43
- parent = parent.slice(0, parent.lastIndexOf("/"));
44
- }
45
- promises.push(
46
- promisifyIDBRequest(
47
- store.put({ url, ...reg, size: encode(data).byteLength })
48
- )
49
- );
50
- }
51
- await Promise.all(promises);
52
- }
53
- }
54
- },
55
- {
56
- name: "fs-blob",
57
- keyPath: "url",
58
- onCreate: async (store) => {
59
- if (initialFiles) {
60
- const promises = [];
61
- for (const [name2, data] of Object.entries(initialFiles)) {
62
- promises.push(
63
- promisifyIDBRequest(
64
- store.put({ url: filenameToURL(name2).href, content: encode(data) })
65
- )
66
- );
67
- }
68
- await Promise.all(promises);
69
- }
70
- }
71
- },
72
- {
73
- name: "viewstate",
74
- keyPath: "url"
75
- }
76
- );
22
+ const { name = "default", browserHistory, initialFiles, entryFile, customFs } = options;
77
23
  this._monaco = promiseWithResolvers();
78
- this._fs = new FS(db);
79
- this._viewState = new WorkspaceStateStorage(db, "viewstate");
24
+ this._fs = customFs ?? new FS("modern-monaco-workspace:" + name, initialFiles);
25
+ this._viewState = new WorkspaceStateStorage("modern-monaco-viewstate:" + name);
80
26
  this._entryFile = entryFile;
81
27
  if (browserHistory) {
82
28
  if (!globalThis.history) {
@@ -170,10 +116,56 @@ var Workspace = class {
170
116
  }
171
117
  };
172
118
  var FS = class {
173
- constructor(_db) {
174
- this._db = _db;
175
- }
176
119
  _watchers = /* @__PURE__ */ new Set();
120
+ _db;
121
+ constructor(scope, initialFiles) {
122
+ this._db = new WorkspaceDatabase(scope, {
123
+ name: "fs-meta",
124
+ keyPath: "url",
125
+ onCreate: async (store) => {
126
+ if (initialFiles) {
127
+ const promises = [];
128
+ const now = Date.now();
129
+ const reg = { type: 1, version: 1, ctime: now, mtime: now, size: 0 };
130
+ const dir = { type: 2, version: 1, ctime: now, mtime: now, size: 0 };
131
+ for (const [name, data] of Object.entries(initialFiles)) {
132
+ const { pathname, href: url } = filenameToURL(name);
133
+ let parent = pathname.slice(0, pathname.lastIndexOf("/"));
134
+ while (parent) {
135
+ promises.push(
136
+ promisifyIDBRequest(
137
+ store.put({ url: toURL(parent).href, ...dir })
138
+ )
139
+ );
140
+ parent = parent.slice(0, parent.lastIndexOf("/"));
141
+ }
142
+ promises.push(
143
+ promisifyIDBRequest(
144
+ store.put({ url, ...reg, size: encode(data).byteLength })
145
+ )
146
+ );
147
+ }
148
+ await Promise.all(promises);
149
+ }
150
+ }
151
+ }, {
152
+ name: "fs-blob",
153
+ keyPath: "url",
154
+ onCreate: async (store) => {
155
+ if (initialFiles) {
156
+ const promises = [];
157
+ for (const [name, data] of Object.entries(initialFiles)) {
158
+ promises.push(
159
+ promisifyIDBRequest(
160
+ store.put({ url: filenameToURL(name).href, content: encode(data) })
161
+ )
162
+ );
163
+ }
164
+ await Promise.all(promises);
165
+ }
166
+ }
167
+ });
168
+ }
177
169
  async _getIdbObjectStore(storeName, readwrite = false) {
178
170
  const db = await this._db.open();
179
171
  return db.transaction(storeName, readwrite ? "readwrite" : "readonly").objectStore(storeName);
@@ -459,8 +451,8 @@ var ErrorNotFound = class extends Error {
459
451
  };
460
452
  var WorkspaceDatabase = class {
461
453
  _db;
462
- constructor(workspaceName, ...stores) {
463
- const open = () => openIDB("modern-monaco-workspace/" + workspaceName, 1, ...stores).then((db) => {
454
+ constructor(name, ...stores) {
455
+ const open = () => openIDB(name, 1, ...stores).then((db) => {
464
456
  db.onclose = () => {
465
457
  this._db = open();
466
458
  };
@@ -473,18 +465,24 @@ var WorkspaceDatabase = class {
473
465
  }
474
466
  };
475
467
  var WorkspaceStateStorage = class {
476
- constructor(_db, _stateName) {
477
- this._db = _db;
478
- this._stateName = _stateName;
468
+ #db;
469
+ constructor(dbName) {
470
+ this.#db = new WorkspaceDatabase(
471
+ dbName,
472
+ {
473
+ name: "store",
474
+ keyPath: "url"
475
+ }
476
+ );
479
477
  }
480
478
  async get(uri) {
481
479
  const url = toURL(uri).href;
482
- const store = (await this._db.open()).transaction(this._stateName, "readonly").objectStore(this._stateName);
480
+ const store = (await this.#db.open()).transaction("store", "readonly").objectStore("store");
483
481
  return promisifyIDBRequest(store.get(url)).then((result) => result?.state);
484
482
  }
485
483
  async save(uri, state) {
486
484
  const url = toURL(uri).href;
487
- const store = (await this._db.open()).transaction(this._stateName, "readwrite").objectStore(this._stateName);
485
+ const store = (await this.#db.open()).transaction("store", "readwrite").objectStore("store");
488
486
  await promisifyIDBRequest(store.put({ url, state }));
489
487
  }
490
488
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "modern-monaco",
3
3
  "description": "A modern version of Monaco Editor",
4
- "version": "0.1.0",
4
+ "version": "0.1.1",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
7
7
  "module": "./dist/index.js",
package/types/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import type monacoNS from "./monaco.d.ts";
2
2
  import type { LSPConfig } from "./lsp.d.ts";
3
3
  import type { TextmateGrammarName, TextmateThemeName } from "./textmate.d.ts";
4
- import type { ErrorNotFound, Workspace } from "./workspace.d.ts";
4
+ import type { ErrorNotFound, FileSystem, Workspace } from "./workspace.d.ts";
5
5
 
6
6
  type Awaitable<T> = T | Promise<T>;
7
7
  type MaybeGetter<T> = Awaitable<MaybeModule<T>> | (() => Awaitable<MaybeModule<T>>);
@@ -67,4 +67,4 @@ export const errors: {
67
67
  NotFound: ErrorNotFound;
68
68
  };
69
69
 
70
- export { Workspace };
70
+ export { Workspace, FileSystem };
@@ -14,6 +14,8 @@ export interface WorkspaceInit {
14
14
  server?: {
15
15
  url: string | URL;
16
16
  };
17
+ /** custom filesystem implementation to override the default IndexedDB filesystem */
18
+ customFs?: FileSystem;
17
19
  }
18
20
 
19
21
  export class Workspace {
@@ -62,13 +64,13 @@ export interface FileSystem {
62
64
  readTextFile(filename: string): Promise<string>;
63
65
  rename(oldName: string, newName: string, options?: { overwrite: boolean }): Promise<void>;
64
66
  stat(filename: string): Promise<FileStat>;
65
- writeFile(filename: string, content: string | Uint8Array): Promise<void>;
67
+ writeFile(filename: string, content: string | Uint8Array, context?: { isModelContentChange: boolean }): Promise<void>;
66
68
  watch(filename: string, options: { recursive: boolean }, handle: FileSystemWatchHandle): () => void;
67
69
  watch(filename: string, handle: FileSystemWatchHandle): () => void;
68
70
  }
69
71
 
70
72
  export interface FileSystemWatchHandle {
71
- (kind: "create" | "modify" | "remove", filename: string, type?: number): void;
73
+ (kind: "create" | "modify" | "remove", filename: string, type?: number, context?: { isModelContentChange: boolean }): void;
72
74
  }
73
75
 
74
76
  export class ErrorNotFound extends Error {}