modern-monaco 0.2.0 → 0.2.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/dist/cache.mjs +3 -3
- package/dist/core.mjs +78 -56
- package/dist/editor-core.mjs +2 -2
- package/dist/index.mjs +2 -26
- package/dist/lsp/{language-service.mjs → client.mjs} +2 -8
- package/dist/lsp/css/setup.mjs +10 -9
- package/dist/lsp/css/worker.mjs +42 -27
- package/dist/lsp/html/setup.mjs +12 -11
- package/dist/lsp/html/worker.mjs +42 -27
- package/dist/lsp/index.mjs +20 -0
- package/dist/lsp/json/setup.mjs +9 -8
- package/dist/lsp/json/worker.mjs +42 -27
- package/dist/lsp/typescript/setup.mjs +9 -9
- package/dist/lsp/typescript/worker.mjs +45 -30
- package/dist/shiki.mjs +3 -3
- package/dist/util.mjs +15 -12
- package/dist/workspace.mjs +22 -17
- package/package.json +7 -1
- package/types/workspace.d.ts +16 -7
package/dist/lsp/json/setup.mjs
CHANGED
|
@@ -111,7 +111,8 @@ var schemas = [
|
|
|
111
111
|
];
|
|
112
112
|
|
|
113
113
|
// src/lsp/json/setup.ts
|
|
114
|
-
import
|
|
114
|
+
import { walk } from "../../workspace.mjs";
|
|
115
|
+
import * as client from "../client.mjs";
|
|
115
116
|
async function setup(monaco, languageId, languageSettings, formattingOptions, workspace) {
|
|
116
117
|
const { editor, languages } = monaco;
|
|
117
118
|
const createData = {
|
|
@@ -132,11 +133,11 @@ async function setup(monaco, languageId, languageSettings, formattingOptions, wo
|
|
|
132
133
|
trimFinalNewlines: true,
|
|
133
134
|
...formattingOptions
|
|
134
135
|
},
|
|
135
|
-
workspace:
|
|
136
|
+
fs: workspace ? await walk(workspace.fs, "/") : void 0
|
|
136
137
|
};
|
|
137
138
|
const worker = editor.createWebWorker({
|
|
138
139
|
worker: getWorker(createData),
|
|
139
|
-
host:
|
|
140
|
+
host: client.createHost(workspace)
|
|
140
141
|
});
|
|
141
142
|
const resetSchema = async (uri) => {
|
|
142
143
|
(await worker.getProxy()).resetSchema(uri.toString());
|
|
@@ -151,9 +152,9 @@ async function setup(monaco, languageId, languageSettings, formattingOptions, wo
|
|
|
151
152
|
resetSchema(event.model.uri);
|
|
152
153
|
}
|
|
153
154
|
});
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
155
|
+
client.registerBasicFeatures(languageId, worker, [" ", ":", '"'], workspace);
|
|
156
|
+
client.registerColorPresentation(languageId, worker);
|
|
157
|
+
client.registerDocumentLinks(languageId, worker);
|
|
157
158
|
languages.registerCodeLensProvider(languageId, {
|
|
158
159
|
provideCodeLenses: function(model, _token) {
|
|
159
160
|
const isImportMap = model.uri.scheme == "file" && ["importmap.json", "import_map.json", "import-map.json", "importMap.json"].some((name) => model.uri.path === "/" + name);
|
|
@@ -249,10 +250,10 @@ function createWebWorker() {
|
|
|
249
250
|
if (workerUrl.origin !== location.origin) {
|
|
250
251
|
return new Worker(
|
|
251
252
|
URL.createObjectURL(new Blob([`import "${workerUrl.href}"`], { type: "application/javascript" })),
|
|
252
|
-
{ type: "module" }
|
|
253
|
+
{ type: "module", name: "json-worker" }
|
|
253
254
|
);
|
|
254
255
|
}
|
|
255
|
-
return new Worker(
|
|
256
|
+
return new Worker(workerUrl, { type: "module", name: "json-worker" });
|
|
256
257
|
}
|
|
257
258
|
function getWorker(createData) {
|
|
258
259
|
const worker = createWebWorker();
|
package/dist/lsp/json/worker.mjs
CHANGED
|
@@ -7682,21 +7682,36 @@ function getLanguageService(params) {
|
|
|
7682
7682
|
|
|
7683
7683
|
// src/lsp/worker-base.ts
|
|
7684
7684
|
var WorkerBase = class {
|
|
7685
|
-
|
|
7686
|
-
this._ctx = _ctx;
|
|
7687
|
-
this._createData = _createData;
|
|
7688
|
-
this._createLanguageDocument = _createLanguageDocument;
|
|
7689
|
-
}
|
|
7690
|
-
#documentCache = /* @__PURE__ */ new Map();
|
|
7685
|
+
#ctx;
|
|
7691
7686
|
#fs;
|
|
7687
|
+
#documentCache = /* @__PURE__ */ new Map();
|
|
7688
|
+
#createLanguageDocument;
|
|
7689
|
+
constructor(ctx, createData, createLanguageDocument) {
|
|
7690
|
+
this.#ctx = ctx;
|
|
7691
|
+
if (createData.fs) {
|
|
7692
|
+
const dirs = /* @__PURE__ */ new Set(["/"]);
|
|
7693
|
+
this.#fs = new Map(createData.fs.map((path) => {
|
|
7694
|
+
const dir = path.slice(0, path.lastIndexOf("/"));
|
|
7695
|
+
if (dir) {
|
|
7696
|
+
dirs.add(dir);
|
|
7697
|
+
}
|
|
7698
|
+
return ["file://" + path, 1];
|
|
7699
|
+
}));
|
|
7700
|
+
for (const dir of dirs) {
|
|
7701
|
+
this.#fs.set("file://" + dir, 2);
|
|
7702
|
+
}
|
|
7703
|
+
createData.fs.length = 0;
|
|
7704
|
+
}
|
|
7705
|
+
this.#createLanguageDocument = createLanguageDocument;
|
|
7706
|
+
}
|
|
7692
7707
|
get hasFileSystemProvider() {
|
|
7693
|
-
return !!this
|
|
7708
|
+
return !!this.#fs;
|
|
7694
7709
|
}
|
|
7695
7710
|
get host() {
|
|
7696
|
-
return this.
|
|
7711
|
+
return this.#ctx.host;
|
|
7697
7712
|
}
|
|
7698
7713
|
getMirrorModels() {
|
|
7699
|
-
return this.
|
|
7714
|
+
return this.#ctx.getMirrorModels();
|
|
7700
7715
|
}
|
|
7701
7716
|
hasModel(fileName) {
|
|
7702
7717
|
const models = this.getMirrorModels();
|
|
@@ -7737,10 +7752,10 @@ var WorkerBase = class {
|
|
|
7737
7752
|
if (cached && cached[0] === version && cached[2]) {
|
|
7738
7753
|
return cached[2];
|
|
7739
7754
|
}
|
|
7740
|
-
if (!this
|
|
7755
|
+
if (!this.#createLanguageDocument) {
|
|
7741
7756
|
throw new Error("createLanguageDocument is not provided");
|
|
7742
7757
|
}
|
|
7743
|
-
const languageDocument = this
|
|
7758
|
+
const languageDocument = this.#createLanguageDocument(document);
|
|
7744
7759
|
this.#documentCache.set(uri, [version, document, languageDocument]);
|
|
7745
7760
|
return languageDocument;
|
|
7746
7761
|
}
|
|
@@ -7751,10 +7766,12 @@ var WorkerBase = class {
|
|
|
7751
7766
|
if (path.startsWith(uri)) {
|
|
7752
7767
|
const name = path.slice(uri.length);
|
|
7753
7768
|
if (!name.includes("/")) {
|
|
7754
|
-
if (type ===
|
|
7755
|
-
|
|
7756
|
-
|
|
7757
|
-
|
|
7769
|
+
if (type === 1) {
|
|
7770
|
+
if (!extensions || extensions.some((ext) => name.endsWith(ext))) {
|
|
7771
|
+
entries.push([name, 1]);
|
|
7772
|
+
}
|
|
7773
|
+
} else if (type === 2) {
|
|
7774
|
+
entries.push([name, 2]);
|
|
7758
7775
|
}
|
|
7759
7776
|
}
|
|
7760
7777
|
}
|
|
@@ -7763,8 +7780,8 @@ var WorkerBase = class {
|
|
|
7763
7780
|
return entries;
|
|
7764
7781
|
}
|
|
7765
7782
|
getFileSystemProvider() {
|
|
7766
|
-
if (this
|
|
7767
|
-
const host = this.
|
|
7783
|
+
if (this.#fs) {
|
|
7784
|
+
const host = this.#ctx.host;
|
|
7768
7785
|
return {
|
|
7769
7786
|
readDirectory: (uri) => {
|
|
7770
7787
|
return Promise.resolve(this.readDir(uri));
|
|
@@ -7781,29 +7798,27 @@ var WorkerBase = class {
|
|
|
7781
7798
|
}
|
|
7782
7799
|
// resolveReference implementes the `DocumentContext` interface
|
|
7783
7800
|
resolveReference(ref, baseUrl) {
|
|
7784
|
-
const
|
|
7785
|
-
|
|
7786
|
-
if (url.protocol === "file:" && url.pathname !== "/" && this.#fs && !this.#fs.has(href.endsWith("/") ? href.slice(0, -1) : href)) {
|
|
7801
|
+
const { protocol, pathname, href } = new URL(ref, baseUrl);
|
|
7802
|
+
if (protocol === "file:" && pathname !== "/" && this.#fs && !this.#fs.has(href.endsWith("/") ? href.slice(0, -1) : href)) {
|
|
7787
7803
|
return void 0;
|
|
7788
7804
|
}
|
|
7789
7805
|
return href;
|
|
7790
7806
|
}
|
|
7791
7807
|
// #region methods used by the host
|
|
7792
|
-
async
|
|
7808
|
+
async releaseDocument(uri) {
|
|
7793
7809
|
this.#documentCache.delete(uri);
|
|
7794
7810
|
}
|
|
7795
7811
|
async fsNotify(kind, path, type) {
|
|
7796
|
-
const
|
|
7797
|
-
const entries = this.#fs ?? (this.#fs = /* @__PURE__ */ new Map());
|
|
7812
|
+
const fs = this.#fs ?? (this.#fs = /* @__PURE__ */ new Map());
|
|
7798
7813
|
if (kind === "create") {
|
|
7799
7814
|
if (type) {
|
|
7800
|
-
|
|
7815
|
+
fs.set(path, type);
|
|
7801
7816
|
}
|
|
7802
7817
|
} else if (kind === "remove") {
|
|
7803
|
-
if (
|
|
7804
|
-
this.#documentCache.delete(
|
|
7818
|
+
if (fs.get(path) === 1) {
|
|
7819
|
+
this.#documentCache.delete(path);
|
|
7805
7820
|
}
|
|
7806
|
-
|
|
7821
|
+
fs.delete(path);
|
|
7807
7822
|
}
|
|
7808
7823
|
}
|
|
7809
7824
|
// #endregion
|
|
@@ -95,8 +95,8 @@ function isSameImports(a, b) {
|
|
|
95
95
|
|
|
96
96
|
// src/lsp/typescript/setup.ts
|
|
97
97
|
import { cache } from "../../cache.mjs";
|
|
98
|
-
import { ErrorNotFound } from "../../workspace.mjs";
|
|
99
|
-
import * as
|
|
98
|
+
import { ErrorNotFound, walk } from "../../workspace.mjs";
|
|
99
|
+
import * as client from "../client.mjs";
|
|
100
100
|
var worker = null;
|
|
101
101
|
async function setup(monaco, languageId, languageSettings, formattingOptions, workspace) {
|
|
102
102
|
if (!worker) {
|
|
@@ -105,10 +105,10 @@ async function setup(monaco, languageId, languageSettings, formattingOptions, wo
|
|
|
105
105
|
if (worker instanceof Promise) {
|
|
106
106
|
worker = await worker;
|
|
107
107
|
}
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
108
|
+
client.registerBasicFeatures(languageId, worker, [".", "/", '"', "'", "<"], workspace);
|
|
109
|
+
client.registerAutoComplete(languageId, worker, [">", "/"]);
|
|
110
|
+
client.registerSignatureHelp(languageId, worker, ["(", ","]);
|
|
111
|
+
client.registerCodeAction(languageId, worker);
|
|
112
112
|
}
|
|
113
113
|
async function createWorker(monaco, workspace, languageSettings, formattingOptions) {
|
|
114
114
|
const fs = workspace?.fs;
|
|
@@ -168,7 +168,7 @@ async function createWorker(monaco, workspace, languageSettings, formattingOptio
|
|
|
168
168
|
},
|
|
169
169
|
importMap,
|
|
170
170
|
types: typesStore.types,
|
|
171
|
-
workspace:
|
|
171
|
+
fs: workspace ? await walk(workspace.fs, "/") : void 0
|
|
172
172
|
};
|
|
173
173
|
const worker2 = monaco.editor.createWebWorker({
|
|
174
174
|
worker: getWorker(createData),
|
|
@@ -282,10 +282,10 @@ function createWebWorker() {
|
|
|
282
282
|
if (workerUrl.origin !== location.origin) {
|
|
283
283
|
return new Worker(
|
|
284
284
|
URL.createObjectURL(new Blob([`import "${workerUrl.href}"`], { type: "application/javascript" })),
|
|
285
|
-
{ type: "module" }
|
|
285
|
+
{ type: "module", name: "typescript-worker" }
|
|
286
286
|
);
|
|
287
287
|
}
|
|
288
|
-
return new Worker(
|
|
288
|
+
return new Worker(workerUrl, { type: "module", name: "typescript-worker" });
|
|
289
289
|
}
|
|
290
290
|
function getWorker(createData) {
|
|
291
291
|
const worker2 = createWebWorker();
|
|
@@ -1466,21 +1466,36 @@ function getWellformedEdit(textEdit) {
|
|
|
1466
1466
|
|
|
1467
1467
|
// src/lsp/worker-base.ts
|
|
1468
1468
|
var WorkerBase = class {
|
|
1469
|
-
|
|
1470
|
-
this._ctx = _ctx;
|
|
1471
|
-
this._createData = _createData;
|
|
1472
|
-
this._createLanguageDocument = _createLanguageDocument;
|
|
1473
|
-
}
|
|
1474
|
-
#documentCache = /* @__PURE__ */ new Map();
|
|
1469
|
+
#ctx;
|
|
1475
1470
|
#fs;
|
|
1471
|
+
#documentCache = /* @__PURE__ */ new Map();
|
|
1472
|
+
#createLanguageDocument;
|
|
1473
|
+
constructor(ctx, createData, createLanguageDocument) {
|
|
1474
|
+
this.#ctx = ctx;
|
|
1475
|
+
if (createData.fs) {
|
|
1476
|
+
const dirs = /* @__PURE__ */ new Set(["/"]);
|
|
1477
|
+
this.#fs = new Map(createData.fs.map((path) => {
|
|
1478
|
+
const dir = path.slice(0, path.lastIndexOf("/"));
|
|
1479
|
+
if (dir) {
|
|
1480
|
+
dirs.add(dir);
|
|
1481
|
+
}
|
|
1482
|
+
return ["file://" + path, 1];
|
|
1483
|
+
}));
|
|
1484
|
+
for (const dir of dirs) {
|
|
1485
|
+
this.#fs.set("file://" + dir, 2);
|
|
1486
|
+
}
|
|
1487
|
+
createData.fs.length = 0;
|
|
1488
|
+
}
|
|
1489
|
+
this.#createLanguageDocument = createLanguageDocument;
|
|
1490
|
+
}
|
|
1476
1491
|
get hasFileSystemProvider() {
|
|
1477
|
-
return !!this
|
|
1492
|
+
return !!this.#fs;
|
|
1478
1493
|
}
|
|
1479
1494
|
get host() {
|
|
1480
|
-
return this.
|
|
1495
|
+
return this.#ctx.host;
|
|
1481
1496
|
}
|
|
1482
1497
|
getMirrorModels() {
|
|
1483
|
-
return this.
|
|
1498
|
+
return this.#ctx.getMirrorModels();
|
|
1484
1499
|
}
|
|
1485
1500
|
hasModel(fileName) {
|
|
1486
1501
|
const models = this.getMirrorModels();
|
|
@@ -1521,10 +1536,10 @@ var WorkerBase = class {
|
|
|
1521
1536
|
if (cached && cached[0] === version && cached[2]) {
|
|
1522
1537
|
return cached[2];
|
|
1523
1538
|
}
|
|
1524
|
-
if (!this
|
|
1539
|
+
if (!this.#createLanguageDocument) {
|
|
1525
1540
|
throw new Error("createLanguageDocument is not provided");
|
|
1526
1541
|
}
|
|
1527
|
-
const languageDocument = this
|
|
1542
|
+
const languageDocument = this.#createLanguageDocument(document2);
|
|
1528
1543
|
this.#documentCache.set(uri, [version, document2, languageDocument]);
|
|
1529
1544
|
return languageDocument;
|
|
1530
1545
|
}
|
|
@@ -1535,10 +1550,12 @@ var WorkerBase = class {
|
|
|
1535
1550
|
if (path.startsWith(uri)) {
|
|
1536
1551
|
const name = path.slice(uri.length);
|
|
1537
1552
|
if (!name.includes("/")) {
|
|
1538
|
-
if (type ===
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1553
|
+
if (type === 1) {
|
|
1554
|
+
if (!extensions || extensions.some((ext) => name.endsWith(ext))) {
|
|
1555
|
+
entries.push([name, 1]);
|
|
1556
|
+
}
|
|
1557
|
+
} else if (type === 2) {
|
|
1558
|
+
entries.push([name, 2]);
|
|
1542
1559
|
}
|
|
1543
1560
|
}
|
|
1544
1561
|
}
|
|
@@ -1547,8 +1564,8 @@ var WorkerBase = class {
|
|
|
1547
1564
|
return entries;
|
|
1548
1565
|
}
|
|
1549
1566
|
getFileSystemProvider() {
|
|
1550
|
-
if (this
|
|
1551
|
-
const host = this.
|
|
1567
|
+
if (this.#fs) {
|
|
1568
|
+
const host = this.#ctx.host;
|
|
1552
1569
|
return {
|
|
1553
1570
|
readDirectory: (uri) => {
|
|
1554
1571
|
return Promise.resolve(this.readDir(uri));
|
|
@@ -1565,29 +1582,27 @@ var WorkerBase = class {
|
|
|
1565
1582
|
}
|
|
1566
1583
|
// resolveReference implementes the `DocumentContext` interface
|
|
1567
1584
|
resolveReference(ref, baseUrl) {
|
|
1568
|
-
const
|
|
1569
|
-
|
|
1570
|
-
if (url.protocol === "file:" && url.pathname !== "/" && this.#fs && !this.#fs.has(href.endsWith("/") ? href.slice(0, -1) : href)) {
|
|
1585
|
+
const { protocol, pathname, href } = new URL(ref, baseUrl);
|
|
1586
|
+
if (protocol === "file:" && pathname !== "/" && this.#fs && !this.#fs.has(href.endsWith("/") ? href.slice(0, -1) : href)) {
|
|
1571
1587
|
return void 0;
|
|
1572
1588
|
}
|
|
1573
1589
|
return href;
|
|
1574
1590
|
}
|
|
1575
1591
|
// #region methods used by the host
|
|
1576
|
-
async
|
|
1592
|
+
async releaseDocument(uri) {
|
|
1577
1593
|
this.#documentCache.delete(uri);
|
|
1578
1594
|
}
|
|
1579
1595
|
async fsNotify(kind, path, type) {
|
|
1580
|
-
const
|
|
1581
|
-
const entries = this.#fs ?? (this.#fs = /* @__PURE__ */ new Map());
|
|
1596
|
+
const fs = this.#fs ?? (this.#fs = /* @__PURE__ */ new Map());
|
|
1582
1597
|
if (kind === "create") {
|
|
1583
1598
|
if (type) {
|
|
1584
|
-
|
|
1599
|
+
fs.set(path, type);
|
|
1585
1600
|
}
|
|
1586
1601
|
} else if (kind === "remove") {
|
|
1587
|
-
if (
|
|
1588
|
-
this.#documentCache.delete(
|
|
1602
|
+
if (fs.get(path) === 1) {
|
|
1603
|
+
this.#documentCache.delete(path);
|
|
1589
1604
|
}
|
|
1590
|
-
|
|
1605
|
+
fs.delete(path);
|
|
1591
1606
|
}
|
|
1592
1607
|
}
|
|
1593
1608
|
// #endregion
|
|
@@ -1639,14 +1654,14 @@ var TypeScriptWorker = class extends WorkerBase {
|
|
|
1639
1654
|
const dirname = path.slice("file:///node_modules/".length);
|
|
1640
1655
|
return Object.keys(this.#importMap.imports).filter((key) => key !== "@jsxRuntime" && (dirname.length === 0 || key.startsWith(dirname))).map((key) => dirname.length > 0 ? key.slice(dirname.length) : key).filter((key) => key !== "/" && key.includes("/")).map((key) => key.split("/")[0]);
|
|
1641
1656
|
}
|
|
1642
|
-
return this.readDir(path).filter(([_, type]) => type === 2
|
|
1657
|
+
return this.readDir(path).filter(([_, type]) => type === 2).map(([name, _]) => name);
|
|
1643
1658
|
}
|
|
1644
1659
|
readDirectory(path, extensions, exclude, include, depth) {
|
|
1645
1660
|
if (path.startsWith("file:///node_modules/")) {
|
|
1646
1661
|
const dirname = path.slice("file:///node_modules/".length);
|
|
1647
1662
|
return Object.keys(this.#importMap.imports).filter((key) => key !== "@jsxRuntime" && (dirname.length === 0 || key.startsWith(dirname))).map((key) => dirname.length > 0 ? key.slice(dirname.length) : key).filter((key) => !key.includes("/"));
|
|
1648
1663
|
}
|
|
1649
|
-
return this.readDir(path, extensions).filter(([_, type]) => type === 1
|
|
1664
|
+
return this.readDir(path, extensions).filter(([_, type]) => type === 1).map(([name, _]) => name);
|
|
1650
1665
|
}
|
|
1651
1666
|
fileExists(filename) {
|
|
1652
1667
|
if (filename.startsWith("/node_modules/")) return false;
|
|
@@ -2298,7 +2313,7 @@ var TypeScriptWorker = class extends WorkerBase {
|
|
|
2298
2313
|
if (types) {
|
|
2299
2314
|
for (const uri of Object.keys(this.#types)) {
|
|
2300
2315
|
if (!(uri in types)) {
|
|
2301
|
-
this.
|
|
2316
|
+
this.releaseDocument(uri);
|
|
2302
2317
|
}
|
|
2303
2318
|
}
|
|
2304
2319
|
this.#types = types;
|
package/dist/shiki.mjs
CHANGED
|
@@ -7917,7 +7917,7 @@ function hashCode(s) {
|
|
|
7917
7917
|
return [...s].reduce((hash, c) => Math.imul(31, hash) + c.charCodeAt(0) | 0, 0);
|
|
7918
7918
|
}
|
|
7919
7919
|
function normalizeFontFamily(fontFamily) {
|
|
7920
|
-
return fontFamily.split(",").map((f) => f.replace(/['"]+/g, "")
|
|
7920
|
+
return fontFamily.split(",").map((f) => f.trim().replace(/['"]+/g, "")).filter(Boolean).map((f) => f.includes(" ") ? `'${f}'` : f).join(", ");
|
|
7921
7921
|
}
|
|
7922
7922
|
|
|
7923
7923
|
// src/shiki-monaco.ts
|
|
@@ -8117,7 +8117,7 @@ function loadTMTheme(src, cdn = "https://esm.sh") {
|
|
|
8117
8117
|
return cache.fetch(url2).then((res) => res.json());
|
|
8118
8118
|
}
|
|
8119
8119
|
const url = typeof src === "string" ? new URL(src, globalThis.location?.href) : src;
|
|
8120
|
-
if (url.protocol === "http" || url.protocol === "https") {
|
|
8120
|
+
if (url.protocol === "http:" || url.protocol === "https:") {
|
|
8121
8121
|
return cache.fetch(url).then((res) => res.json());
|
|
8122
8122
|
}
|
|
8123
8123
|
throw new Error(`Unsupported theme source: ${src}`);
|
|
@@ -8131,7 +8131,7 @@ function loadTMGrammar(src, cdn = "https://esm.sh") {
|
|
|
8131
8131
|
}
|
|
8132
8132
|
}
|
|
8133
8133
|
const url = typeof src === "string" ? new URL(src, globalThis.location?.href) : src;
|
|
8134
|
-
if (url.protocol === "http" || url.protocol === "https") {
|
|
8134
|
+
if (url.protocol === "http:" || url.protocol === "https:") {
|
|
8135
8135
|
return cache.fetch(url).then((res) => res.json());
|
|
8136
8136
|
}
|
|
8137
8137
|
throw new Error(`Unsupported grammar source: ${src}`);
|
package/dist/util.mjs
CHANGED
|
@@ -10,7 +10,7 @@ function decode(data) {
|
|
|
10
10
|
function defineProperty(obj, prop, value) {
|
|
11
11
|
Object.defineProperty(obj, prop, { value });
|
|
12
12
|
}
|
|
13
|
-
function
|
|
13
|
+
function normalizeURL(uri) {
|
|
14
14
|
return uri instanceof URL ? uri : new URL(uri, "file:///");
|
|
15
15
|
}
|
|
16
16
|
function filenameToURL(filename) {
|
|
@@ -131,10 +131,10 @@ function promisifyIDBRequest(req) {
|
|
|
131
131
|
});
|
|
132
132
|
}
|
|
133
133
|
async function openIDB(name, version = 1, ...stores) {
|
|
134
|
-
const
|
|
134
|
+
const openRequest = indexedDB.open(name, version);
|
|
135
135
|
const promises = [];
|
|
136
|
-
|
|
137
|
-
const db2 =
|
|
136
|
+
openRequest.onupgradeneeded = () => {
|
|
137
|
+
const db2 = openRequest.result;
|
|
138
138
|
for (const { name: name2, keyPath, onCreate } of stores) {
|
|
139
139
|
if (!db2.objectStoreNames.contains(name2)) {
|
|
140
140
|
const store = db2.createObjectStore(name2, { keyPath });
|
|
@@ -144,15 +144,15 @@ async function openIDB(name, version = 1, ...stores) {
|
|
|
144
144
|
}
|
|
145
145
|
}
|
|
146
146
|
};
|
|
147
|
-
const db = await promisifyIDBRequest(
|
|
147
|
+
const db = await promisifyIDBRequest(openRequest);
|
|
148
148
|
await Promise.all(promises);
|
|
149
149
|
return db;
|
|
150
150
|
}
|
|
151
151
|
function openIDBCursor(store, range, callback, direction) {
|
|
152
152
|
return new Promise((resolve, reject) => {
|
|
153
|
-
const
|
|
154
|
-
|
|
155
|
-
const cursor =
|
|
153
|
+
const corsor = store.openCursor(range, direction);
|
|
154
|
+
corsor.onsuccess = () => {
|
|
155
|
+
const cursor = corsor.result;
|
|
156
156
|
if (cursor) {
|
|
157
157
|
if (callback(cursor) !== false) {
|
|
158
158
|
cursor.continue();
|
|
@@ -161,12 +161,15 @@ function openIDBCursor(store, range, callback, direction) {
|
|
|
161
161
|
}
|
|
162
162
|
resolve();
|
|
163
163
|
};
|
|
164
|
-
|
|
165
|
-
reject(
|
|
164
|
+
corsor.onerror = () => {
|
|
165
|
+
reject(corsor.error);
|
|
166
166
|
};
|
|
167
167
|
});
|
|
168
168
|
}
|
|
169
169
|
function promiseWithResolvers() {
|
|
170
|
+
if (Promise.withResolvers) {
|
|
171
|
+
return Promise.withResolvers();
|
|
172
|
+
}
|
|
170
173
|
let resolve;
|
|
171
174
|
let reject;
|
|
172
175
|
const promise = new Promise((res, rej) => {
|
|
@@ -187,10 +190,10 @@ export {
|
|
|
187
190
|
filenameToURL,
|
|
188
191
|
isDigital,
|
|
189
192
|
isPlainObject,
|
|
193
|
+
normalizeURL,
|
|
190
194
|
openIDB,
|
|
191
195
|
openIDBCursor,
|
|
192
196
|
promiseWithResolvers,
|
|
193
197
|
promisifyIDBRequest,
|
|
194
|
-
supportLocalStorage
|
|
195
|
-
toURL
|
|
198
|
+
supportLocalStorage
|
|
196
199
|
};
|
package/dist/workspace.mjs
CHANGED
|
@@ -5,12 +5,12 @@ import {
|
|
|
5
5
|
decode,
|
|
6
6
|
encode,
|
|
7
7
|
filenameToURL,
|
|
8
|
+
normalizeURL,
|
|
8
9
|
openIDB,
|
|
9
10
|
openIDBCursor,
|
|
10
11
|
promiseWithResolvers,
|
|
11
12
|
promisifyIDBRequest,
|
|
12
|
-
supportLocalStorage
|
|
13
|
-
toURL
|
|
13
|
+
supportLocalStorage
|
|
14
14
|
} from "./util.mjs";
|
|
15
15
|
var Workspace = class {
|
|
16
16
|
_monaco;
|
|
@@ -21,14 +21,14 @@ var Workspace = class {
|
|
|
21
21
|
constructor(options = {}) {
|
|
22
22
|
const { name = "default", browserHistory, initialFiles, entryFile, customFS } = options;
|
|
23
23
|
this._monaco = promiseWithResolvers();
|
|
24
|
-
this._fs = customFS ?? new
|
|
24
|
+
this._fs = customFS ?? new IndexedDBFileSystem("modern-monaco-workspace(" + name + ")");
|
|
25
25
|
this._viewState = new WorkspaceStateStorage("modern-monaco-state(" + name + ")");
|
|
26
26
|
this._entryFile = entryFile;
|
|
27
27
|
if (initialFiles) {
|
|
28
28
|
for (const [name2, data] of Object.entries(initialFiles)) {
|
|
29
29
|
void this._fs.stat(name2).catch(async (err) => {
|
|
30
30
|
if (err instanceof ErrorNotFound) {
|
|
31
|
-
const { pathname
|
|
31
|
+
const { pathname } = filenameToURL(name2);
|
|
32
32
|
const dir = pathname.slice(0, pathname.lastIndexOf("/"));
|
|
33
33
|
if (dir) {
|
|
34
34
|
await this._fs.createDirectory(dir);
|
|
@@ -68,11 +68,10 @@ var Workspace = class {
|
|
|
68
68
|
const monaco = await this._monaco.promise;
|
|
69
69
|
return this._openTextDocument(uri, monaco.editor.getEditors()[0], void 0, content);
|
|
70
70
|
}
|
|
71
|
-
// @internal
|
|
72
71
|
async _openTextDocument(uri, editor, selectionOrPosition, readonlyContent) {
|
|
73
72
|
const monaco = await this._monaco.promise;
|
|
74
73
|
const fs = this._fs;
|
|
75
|
-
const href =
|
|
74
|
+
const href = normalizeURL(uri).href;
|
|
76
75
|
const content = readonlyContent ?? await fs.readTextFile(href);
|
|
77
76
|
const viewState = await this.viewState.get(href);
|
|
78
77
|
const modelUri = monaco.Uri.parse(href);
|
|
@@ -137,7 +136,7 @@ var Workspace = class {
|
|
|
137
136
|
return monaco.showQuickPick(items, options, token);
|
|
138
137
|
}
|
|
139
138
|
};
|
|
140
|
-
var
|
|
139
|
+
var IndexedDBFileSystem = class {
|
|
141
140
|
_watchers = /* @__PURE__ */ new Set();
|
|
142
141
|
_db;
|
|
143
142
|
constructor(scope) {
|
|
@@ -155,13 +154,6 @@ var FS = class {
|
|
|
155
154
|
const transaction = (await this._db.open()).transaction(["fs-meta", "fs-blob"], readwrite ? "readwrite" : "readonly");
|
|
156
155
|
return [transaction.objectStore("fs-meta"), transaction.objectStore("fs-blob")];
|
|
157
156
|
}
|
|
158
|
-
async *walk() {
|
|
159
|
-
const metaStore = await this._getIdbObjectStore("fs-meta");
|
|
160
|
-
const entries = await promisifyIDBRequest(metaStore.getAll());
|
|
161
|
-
for (const entry of entries) {
|
|
162
|
-
yield [new URL(entry.url).pathname, entry.type];
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
157
|
async stat(name) {
|
|
166
158
|
const url = filenameToURL(name).href;
|
|
167
159
|
if (url === "file:///") {
|
|
@@ -428,6 +420,18 @@ var ErrorNotFound = class extends Error {
|
|
|
428
420
|
super("No such file or directory: " + name);
|
|
429
421
|
}
|
|
430
422
|
};
|
|
423
|
+
async function walk(fs, dir = "/") {
|
|
424
|
+
const entries = [];
|
|
425
|
+
for (const [name, type] of await fs.readDirectory(dir || "/")) {
|
|
426
|
+
const path = (dir.endsWith("/") ? dir.slice(0, -1) : dir) + "/" + name;
|
|
427
|
+
if (type === 2) {
|
|
428
|
+
entries.push(...await walk(fs, path));
|
|
429
|
+
} else {
|
|
430
|
+
entries.push(path);
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
return entries;
|
|
434
|
+
}
|
|
431
435
|
var WorkspaceDatabase = class {
|
|
432
436
|
_db;
|
|
433
437
|
constructor(name, ...stores) {
|
|
@@ -455,12 +459,12 @@ var WorkspaceStateStorage = class {
|
|
|
455
459
|
);
|
|
456
460
|
}
|
|
457
461
|
async get(uri) {
|
|
458
|
-
const url =
|
|
462
|
+
const url = normalizeURL(uri).href;
|
|
459
463
|
const store = (await this.#db.open()).transaction("store", "readonly").objectStore("store");
|
|
460
464
|
return promisifyIDBRequest(store.get(url)).then((result) => result?.state);
|
|
461
465
|
}
|
|
462
466
|
async save(uri, state) {
|
|
463
|
-
const url =
|
|
467
|
+
const url = normalizeURL(uri).href;
|
|
464
468
|
const store = (await this.#db.open()).transaction("store", "readwrite").objectStore("store");
|
|
465
469
|
await promisifyIDBRequest(store.put({ url, state }));
|
|
466
470
|
}
|
|
@@ -584,5 +588,6 @@ var BrowserHistory = class {
|
|
|
584
588
|
};
|
|
585
589
|
export {
|
|
586
590
|
ErrorNotFound,
|
|
587
|
-
Workspace
|
|
591
|
+
Workspace,
|
|
592
|
+
walk
|
|
588
593
|
};
|
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.2.
|
|
4
|
+
"version": "0.2.2",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.mjs",
|
|
7
7
|
"module": "./dist/index.mjs",
|
|
@@ -31,6 +31,9 @@
|
|
|
31
31
|
"./editor-worker": {
|
|
32
32
|
"import": "./dist/editor-worker.mjs"
|
|
33
33
|
},
|
|
34
|
+
"./editor-worker-main": {
|
|
35
|
+
"import": "./dist/editor-worker-main.mjs"
|
|
36
|
+
},
|
|
34
37
|
"./cache": {
|
|
35
38
|
"import": "./dist/cache.mjs"
|
|
36
39
|
},
|
|
@@ -40,6 +43,9 @@
|
|
|
40
43
|
"./util": {
|
|
41
44
|
"import": "./dist/util.mjs"
|
|
42
45
|
},
|
|
46
|
+
"./lsp": {
|
|
47
|
+
"import": "./dist/lsp/index.mjs"
|
|
48
|
+
},
|
|
43
49
|
"./lsp/*": {
|
|
44
50
|
"import": "./dist/lsp/*.mjs"
|
|
45
51
|
}
|
package/types/workspace.d.ts
CHANGED
|
@@ -43,9 +43,23 @@ export interface WorkspaceHistory {
|
|
|
43
43
|
onChange(callback: (state: WorkspaceHistoryState) => void): () => void;
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
/**
|
|
46
|
+
/**
|
|
47
|
+
* The type of a file system entry.
|
|
48
|
+
* - `0`: unknown
|
|
49
|
+
* - `1`: file
|
|
50
|
+
* - `2`: directory
|
|
51
|
+
* - `64`: symlink
|
|
52
|
+
*/
|
|
47
53
|
export type FileSystemEntryType = 0 | 1 | 2 | 64;
|
|
48
54
|
|
|
55
|
+
export interface FileSystemWatchContext {
|
|
56
|
+
isModelContentChange?: boolean;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export interface FileSystemWatchHandle {
|
|
60
|
+
(kind: "create" | "modify" | "remove", filename: string, type?: number, context?: FileSystemWatchContext): void;
|
|
61
|
+
}
|
|
62
|
+
|
|
49
63
|
export interface FileStat {
|
|
50
64
|
readonly type: FileSystemEntryType;
|
|
51
65
|
readonly ctime: number;
|
|
@@ -63,14 +77,9 @@ export interface FileSystem {
|
|
|
63
77
|
readTextFile(filename: string): Promise<string>;
|
|
64
78
|
rename(oldName: string, newName: string, options?: { overwrite: boolean }): Promise<void>;
|
|
65
79
|
stat(filename: string): Promise<FileStat>;
|
|
66
|
-
writeFile(filename: string, content: string | Uint8Array, context?:
|
|
80
|
+
writeFile(filename: string, content: string | Uint8Array, context?: FileSystemWatchContext): Promise<void>;
|
|
67
81
|
watch(filename: string, options: { recursive: boolean }, handle: FileSystemWatchHandle): () => void;
|
|
68
82
|
watch(filename: string, handle: FileSystemWatchHandle): () => void;
|
|
69
|
-
walk(): AsyncIterable<[string, FileSystemEntryType]>;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
export interface FileSystemWatchHandle {
|
|
73
|
-
(kind: "create" | "modify" | "remove", filename: string, type?: number, context?: { isModelContentChange: boolean }): void;
|
|
74
83
|
}
|
|
75
84
|
|
|
76
85
|
export class ErrorNotFound extends Error {}
|