@nola-lang/typescript-plugin 0.1.0-alpha.0 → 0.1.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.
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,MAAM,YAAY,CAAC;AAMjC,qEAAqE;AACrE,wBAAgB,kBAAkB,IAAI,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAWlE"}
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,MAAM,YAAY,CAAC;AAOjC,qEAAqE;AACrE,wBAAgB,kBAAkB,IAAI,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAgBlE"}
package/dist/plugin.js CHANGED
@@ -11,6 +11,7 @@ import { findProjectRoot } from "@nola-lang/node-loader";
11
11
  import { createLanguageServicePlugin } from "@volar/typescript/lib/quickstart/createLanguageServicePlugin.js";
12
12
  import { decorateHostWithCompanions } from "./companion-host.js";
13
13
  import { guardProjectServiceDocumentCache } from "./document-cache-guard.js";
14
+ import { decorateHostForTsiResolutionWatch } from "./resolution-watch.js";
14
15
  import { decorateServerHostForCompanions } from "./server-host.js";
15
16
  import { decorateHostHideShadowedDeclarations } from "./shadowed-declarations.js";
16
17
  /** tsserver plugin factory; loaded via the CJS bundle in Track 3. */
@@ -23,6 +24,11 @@ export function createNolaTsPlugin() {
23
24
  decorateHostWithCompanions(typescript, info.languageServiceHost, { sourceRoot });
24
25
  return {
25
26
  languagePlugins: [createNolaLanguagePlugin((fileName) => fileName, { sourceRoot })],
27
+ // setup runs AFTER Volar's decorateLanguageServiceHost, so this wraps the
28
+ // resolver that actually handles `.tsi` literals (see resolution-watch.ts).
29
+ setup: () => {
30
+ decorateHostForTsiResolutionWatch(info.languageServiceHost, info.serverHost, info.project, [".tsi"]);
31
+ },
26
32
  };
27
33
  });
28
34
  }
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,6DAA6D;AAC7D,+EAA+E;AAC/E,2FAA2F;AAC3F,+EAA+E;AAC/E,qEAAqE;AACrE,wDAAwD;AACxD,2FAA2F;AAC3F,OAAO,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AACpE,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,2BAA2B,EAAE,MAAM,iEAAiE,CAAC;AAE9G,OAAO,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAC;AACjE,OAAO,EAAE,gCAAgC,EAAE,MAAM,2BAA2B,CAAC;AAC7E,OAAO,EAAE,+BAA+B,EAAE,MAAM,kBAAkB,CAAC;AACnE,OAAO,EAAE,oCAAoC,EAAE,MAAM,4BAA4B,CAAC;AAElF,qEAAqE;AACrE,MAAM,UAAU,kBAAkB;IAChC,OAAO,2BAA2B,CAAC,CAAC,UAAU,EAAE,IAAI,EAAE,EAAE;QACtD,MAAM,UAAU,GAAG,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAAC;QACvE,gCAAgC,CAAE,IAAI,CAAC,OAAkD,CAAC,cAAc,CAAC,CAAC;QAC1G,+BAA+B,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACjD,oCAAoC,CAAC,UAAU,EAAE,IAAI,CAAC,mBAAmB,CAAC,CAAC;QAC3E,0BAA0B,CAAC,UAAU,EAAE,IAAI,CAAC,mBAAmB,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC;QACjF,OAAO;YACL,eAAe,EAAE,CAAC,wBAAwB,CAAS,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC;SAC5F,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,6DAA6D;AAC7D,+EAA+E;AAC/E,2FAA2F;AAC3F,+EAA+E;AAC/E,qEAAqE;AACrE,wDAAwD;AACxD,2FAA2F;AAC3F,OAAO,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AACpE,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,2BAA2B,EAAE,MAAM,iEAAiE,CAAC;AAE9G,OAAO,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAC;AACjE,OAAO,EAAE,gCAAgC,EAAE,MAAM,2BAA2B,CAAC;AAC7E,OAAO,EAAE,iCAAiC,EAAE,MAAM,uBAAuB,CAAC;AAC1E,OAAO,EAAE,+BAA+B,EAAE,MAAM,kBAAkB,CAAC;AACnE,OAAO,EAAE,oCAAoC,EAAE,MAAM,4BAA4B,CAAC;AAElF,qEAAqE;AACrE,MAAM,UAAU,kBAAkB;IAChC,OAAO,2BAA2B,CAAC,CAAC,UAAU,EAAE,IAAI,EAAE,EAAE;QACtD,MAAM,UAAU,GAAG,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAAC;QACvE,gCAAgC,CAAE,IAAI,CAAC,OAAkD,CAAC,cAAc,CAAC,CAAC;QAC1G,+BAA+B,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACjD,oCAAoC,CAAC,UAAU,EAAE,IAAI,CAAC,mBAAmB,CAAC,CAAC;QAC3E,0BAA0B,CAAC,UAAU,EAAE,IAAI,CAAC,mBAAmB,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC;QACjF,OAAO;YACL,eAAe,EAAE,CAAC,wBAAwB,CAAS,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC;YAC3F,0EAA0E;YAC1E,4EAA4E;YAC5E,KAAK,EAAE,GAAG,EAAE;gBACV,iCAAiC,CAAC,IAAI,CAAC,mBAAmB,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;YACvG,CAAC;SACF,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,30 @@
1
+ import type ts from "typescript";
2
+ /**
3
+ * Re-resolution bridge for deleted-then-recreated `.tsi` imports.
4
+ *
5
+ * Volar's host decoration resolves a `.tsi`-suffixed literal with its OWN
6
+ * resolver (it intercepts probes for the phantom `x.d.tsi.ts` and checks the
7
+ * real `x.tsi`), bypassing tsserver's resolution cache for those literals.
8
+ * Two consequences when the target file is missing: the recorded failed
9
+ * lookups name only the phantom paths, and — worse — tsserver never sees the
10
+ * resolution at all, so it installs no failed-lookup watcher and has no
11
+ * trigger to ever re-resolve. Deleting a `.tsi` produced TS2307 immediately
12
+ * (it was a watched program file), but re-creating it left the error stuck
13
+ * until the importing file was closed and reopened.
14
+ *
15
+ * This decoration wraps the (Volar-decorated) `resolveModuleNameLiterals`:
16
+ * when a relative `.tsi` literal fails to resolve, it watches the candidate
17
+ * path via the ServerHost; on any event it marks the importing files'
18
+ * resolutions invalidated, dirties the project, and refreshes diagnostics —
19
+ * the next program synchronize then re-resolves exactly those files. The
20
+ * watcher is PERSISTENT (never closed once armed): after the delete/revive
21
+ * cycle the revived ScriptInfo reloads content but no longer dirties the
22
+ * project on change (verified: a stale TS2305 cleared instantly on an
23
+ * unrelated nudge), so the same watcher doubles as the change trigger for
24
+ * every later edit of that file — content restored, emptied again, or
25
+ * re-deleted. Must be installed AFTER Volar's decoration (the plugin's
26
+ * `setup` hook) so the wrapped prior is the resolver that actually handles
27
+ * `.tsi`.
28
+ */
29
+ export declare function decorateHostForTsiResolutionWatch(host: ts.LanguageServiceHost, serverHost: ts.server.ServerHost, project: ts.server.Project, extensions: string[]): void;
30
+ //# sourceMappingURL=resolution-watch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolution-watch.d.ts","sourceRoot":"","sources":["../src/resolution-watch.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,YAAY,CAAC;AAEjC;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,iCAAiC,CAC/C,IAAI,EAAE,EAAE,CAAC,mBAAmB,EAC5B,UAAU,EAAE,EAAE,CAAC,MAAM,CAAC,UAAU,EAChC,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,EAC1B,UAAU,EAAE,MAAM,EAAE,GACnB,IAAI,CA2EN"}
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Re-resolution bridge for deleted-then-recreated `.tsi` imports.
3
+ *
4
+ * Volar's host decoration resolves a `.tsi`-suffixed literal with its OWN
5
+ * resolver (it intercepts probes for the phantom `x.d.tsi.ts` and checks the
6
+ * real `x.tsi`), bypassing tsserver's resolution cache for those literals.
7
+ * Two consequences when the target file is missing: the recorded failed
8
+ * lookups name only the phantom paths, and — worse — tsserver never sees the
9
+ * resolution at all, so it installs no failed-lookup watcher and has no
10
+ * trigger to ever re-resolve. Deleting a `.tsi` produced TS2307 immediately
11
+ * (it was a watched program file), but re-creating it left the error stuck
12
+ * until the importing file was closed and reopened.
13
+ *
14
+ * This decoration wraps the (Volar-decorated) `resolveModuleNameLiterals`:
15
+ * when a relative `.tsi` literal fails to resolve, it watches the candidate
16
+ * path via the ServerHost; on any event it marks the importing files'
17
+ * resolutions invalidated, dirties the project, and refreshes diagnostics —
18
+ * the next program synchronize then re-resolves exactly those files. The
19
+ * watcher is PERSISTENT (never closed once armed): after the delete/revive
20
+ * cycle the revived ScriptInfo reloads content but no longer dirties the
21
+ * project on change (verified: a stale TS2305 cleared instantly on an
22
+ * unrelated nudge), so the same watcher doubles as the change trigger for
23
+ * every later edit of that file — content restored, emptied again, or
24
+ * re-deleted. Must be installed AFTER Volar's decoration (the plugin's
25
+ * `setup` hook) so the wrapped prior is the resolver that actually handles
26
+ * `.tsi`.
27
+ */
28
+ export function decorateHostForTsiResolutionWatch(host, serverHost, project, extensions) {
29
+ const prior = host.resolveModuleNameLiterals?.bind(host);
30
+ if (!prior)
31
+ return;
32
+ // 500 = tsserver's PollingInterval.Medium; the polling fallback watcher
33
+ // requires an explicit interval (undefined throws in Node's fs.watchFile).
34
+ const watchFile = (path, cb) => serverHost.watchFile(path, cb, 500);
35
+ const caseSensitive = typeof host.useCaseSensitiveFileNames === "function"
36
+ ? host.useCaseSensitiveFileNames()
37
+ : (host.useCaseSensitiveFileNames ?? false);
38
+ const canon = (fileName) => {
39
+ const posix = fileName.replace(/\\/g, "/");
40
+ return caseSensitive ? posix : posix.toLowerCase();
41
+ };
42
+ const watched = new Map();
43
+ const invalidated = new Set();
44
+ const hostWithInvalidation = host;
45
+ // markAsDirty is internal-but-stable: it bumps the project version so the
46
+ // next synchronize actually rebuilds the program.
47
+ const projectWithDirty = project;
48
+ // Project.updateGraphWorker REASSIGNS `this.hasInvalidatedResolutions` on
49
+ // every graph update (from its resolutionCache), so a plain property
50
+ // override is clobbered before synchronizeHostData ever reads it. An
51
+ // accessor keeps ours composed on top: the setter captures tsserver's
52
+ // function as the inner delegate, the getter serves the composition.
53
+ let innerHasInvalidated = hostWithInvalidation.hasInvalidatedResolutions;
54
+ const composedHasInvalidated = (path) => invalidated.has(canon(path)) || (innerHasInvalidated?.(path) ?? false);
55
+ Object.defineProperty(host, "hasInvalidatedResolutions", {
56
+ configurable: true,
57
+ get: () => composedHasInvalidated,
58
+ set: (fn) => {
59
+ innerHasInvalidated = fn;
60
+ },
61
+ });
62
+ host.resolveModuleNameLiterals = (moduleLiterals, containingFile, ...rest) => {
63
+ const containing = canon(containingFile);
64
+ invalidated.delete(containing);
65
+ const results = prior(moduleLiterals, containingFile, ...rest);
66
+ for (let i = 0; i < moduleLiterals.length; i++) {
67
+ const text = moduleLiterals[i]?.text ?? "";
68
+ if (!text.startsWith("./") && !text.startsWith("../"))
69
+ continue;
70
+ if (!extensions.some((ext) => text.endsWith(ext)))
71
+ continue;
72
+ const dir = containingFile.replace(/\\/g, "/").split("/").slice(0, -1).join("/");
73
+ const candidate = canon(`${dir}/${text}`.replace(/\/\.\//g, "/"));
74
+ const entry = watched.get(candidate);
75
+ if (entry) {
76
+ entry.waiters.add(containing);
77
+ continue;
78
+ }
79
+ // arm only on failure; a healthy never-deleted file keeps tsserver's own
80
+ // ScriptInfo watching and needs no bridge
81
+ if (results[i]?.resolvedModule)
82
+ continue;
83
+ const waiters = new Set([containing]);
84
+ const watcher = watchFile(candidate, () => {
85
+ for (const waiter of waiters)
86
+ invalidated.add(waiter);
87
+ projectWithDirty.markAsDirty?.();
88
+ project.refreshDiagnostics();
89
+ });
90
+ watched.set(candidate, { watcher, waiters });
91
+ }
92
+ return results;
93
+ };
94
+ }
95
+ //# sourceMappingURL=resolution-watch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolution-watch.js","sourceRoot":"","sources":["../src/resolution-watch.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@nola-lang/typescript-plugin",
3
- "version": "0.1.0-alpha.0",
3
+ "version": "0.1.2",
4
4
  "description": "tsserver plugin serving .tsi to TypeScript editors (internal editor layer)",
5
5
  "keywords": [
6
6
  "nola"
7
7
  ],
8
- "license": "MIT",
8
+ "license": "Apache-2.0",
9
9
  "author": "Evgen Mykhailenko",
10
10
  "homepage": "https://github.com/nola-lang/nola#readme",
11
11
  "repository": {
@@ -29,15 +29,16 @@
29
29
  }
30
30
  },
31
31
  "files": [
32
- "dist"
32
+ "dist",
33
+ "!dist/.tsbuildinfo"
33
34
  ],
34
35
  "scripts": {
35
36
  "bundle": "node scripts/bundle.mjs"
36
37
  },
37
38
  "dependencies": {
38
- "@nola-lang/compiler": "0.1.0-alpha.0",
39
- "@nola-lang/language-core": "0.1.0-alpha.0",
40
- "@nola-lang/node-loader": "0.1.0-alpha.0",
39
+ "@nola-lang/compiler": "0.1.2",
40
+ "@nola-lang/language-core": "0.1.2",
41
+ "@nola-lang/node-loader": "0.1.2",
41
42
  "@volar/typescript": "2.4.28"
42
43
  },
43
44
  "devDependencies": {