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 +20 -0
- package/dist/workspace.js +65 -67
- package/package.json +1 -1
- package/types/index.d.ts +2 -2
- package/types/workspace.d.ts +4 -2
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(
|
|
79
|
-
this._viewState = new WorkspaceStateStorage(
|
|
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(
|
|
463
|
-
const open = () => openIDB(
|
|
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
|
-
|
|
477
|
-
|
|
478
|
-
this
|
|
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.
|
|
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.
|
|
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
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 };
|
package/types/workspace.d.ts
CHANGED
|
@@ -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 {}
|