@bleedingdev/modern-js-renderer-octane 0.0.0-bootstrap → 3.9.3-ultramodern.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.
Files changed (137) hide show
  1. package/LICENSE +21 -0
  2. package/bin/octane-tsc.mjs +4 -0
  3. package/dist/cjs/bootstrap.js +68 -0
  4. package/dist/cjs/client.js +371 -0
  5. package/dist/cjs/entry-application.js +83 -0
  6. package/dist/cjs/entry-client.js +92 -0
  7. package/dist/cjs/entry-server.js +127 -0
  8. package/dist/cjs/federation-context.js +72 -0
  9. package/dist/cjs/federation.js +103 -0
  10. package/dist/cjs/i18n/I18nProvider.js +67 -0
  11. package/dist/cjs/i18n/LocalizedLink.js +89 -0
  12. package/dist/cjs/i18n/context.js +41 -0
  13. package/dist/cjs/i18n/index.js +86 -0
  14. package/dist/cjs/i18n/languageSync.js +99 -0
  15. package/dist/cjs/i18n/types.js +18 -0
  16. package/dist/cjs/i18n/useI18n.js +110 -0
  17. package/dist/cjs/index.js +46 -0
  18. package/dist/cjs/manifest.js +167 -0
  19. package/dist/cjs/plugin/compiler.js +125 -0
  20. package/dist/cjs/plugin/create.js +265 -0
  21. package/dist/cjs/plugin/index.js +151 -0
  22. package/dist/cjs/plugin/profile.js +89 -0
  23. package/dist/cjs/plugin/source.js +56 -0
  24. package/dist/cjs/router-client.js +139 -0
  25. package/dist/cjs/router-handler.js +168 -0
  26. package/dist/cjs/router-injection.js +139 -0
  27. package/dist/cjs/router-server-cleanup.js +46 -0
  28. package/dist/cjs/router-server-snapshot.js +405 -0
  29. package/dist/cjs/router-server.js +108 -0
  30. package/dist/cjs/router-snapshot.js +270 -0
  31. package/dist/cjs/router.js +218 -0
  32. package/dist/cjs/routes.js +187 -0
  33. package/dist/cjs/server.js +224 -0
  34. package/dist/cjs/typecheck.js +615 -0
  35. package/dist/esm/bootstrap.mjs +24 -0
  36. package/dist/esm/client.mjs +327 -0
  37. package/dist/esm/entry-application.mjs +39 -0
  38. package/dist/esm/entry-client.mjs +54 -0
  39. package/dist/esm/entry-server.mjs +86 -0
  40. package/dist/esm/federation-context.mjs +25 -0
  41. package/dist/esm/federation.mjs +65 -0
  42. package/dist/esm/i18n/I18nProvider.mjs +29 -0
  43. package/dist/esm/i18n/LocalizedLink.mjs +48 -0
  44. package/dist/esm/i18n/context.mjs +3 -0
  45. package/dist/esm/i18n/index.mjs +8 -0
  46. package/dist/esm/i18n/languageSync.mjs +61 -0
  47. package/dist/esm/i18n/types.mjs +0 -0
  48. package/dist/esm/i18n/useI18n.mjs +72 -0
  49. package/dist/esm/index.mjs +8 -0
  50. package/dist/esm/manifest.mjs +117 -0
  51. package/dist/esm/router-client.mjs +98 -0
  52. package/dist/esm/router-handler.mjs +130 -0
  53. package/dist/esm/router-injection.mjs +101 -0
  54. package/dist/esm/router-server-cleanup.mjs +8 -0
  55. package/dist/esm/router-server-snapshot.mjs +367 -0
  56. package/dist/esm/router-server.mjs +12 -0
  57. package/dist/esm/router-snapshot.mjs +199 -0
  58. package/dist/esm/router.mjs +94 -0
  59. package/dist/esm/routes.mjs +134 -0
  60. package/dist/esm/server.mjs +183 -0
  61. package/dist/esm-node/bootstrap.mjs +24 -0
  62. package/dist/esm-node/manifest.mjs +117 -0
  63. package/dist/esm-node/plugin/compiler.mjs +70 -0
  64. package/dist/esm-node/plugin/create.mjs +227 -0
  65. package/dist/esm-node/plugin/index.mjs +103 -0
  66. package/dist/esm-node/plugin/profile.mjs +51 -0
  67. package/dist/esm-node/plugin/source.mjs +7 -0
  68. package/dist/esm-node/typecheck.mjs +560 -0
  69. package/dist/types/bootstrap.d.ts +10 -0
  70. package/dist/types/client.d.ts +36 -0
  71. package/dist/types/entry-application.d.ts +19 -0
  72. package/dist/types/entry-client.d.ts +8 -0
  73. package/dist/types/entry-server.d.ts +11 -0
  74. package/dist/types/federation-context.d.ts +28 -0
  75. package/dist/types/federation.d.ts +18 -0
  76. package/dist/types/i18n/I18nProvider.d.ts +8 -0
  77. package/dist/types/i18n/LocalizedLink.d.ts +41 -0
  78. package/dist/types/i18n/context.d.ts +9 -0
  79. package/dist/types/i18n/index.d.ts +9 -0
  80. package/dist/types/i18n/languageSync.d.ts +26 -0
  81. package/dist/types/i18n/types.d.ts +34 -0
  82. package/dist/types/i18n/useI18n.d.ts +21 -0
  83. package/dist/types/index.d.ts +9 -0
  84. package/dist/types/manifest.d.ts +34 -0
  85. package/dist/types/plugin/compiler-manifest.d.cts +10 -0
  86. package/dist/types/plugin/compiler.d.ts +5 -0
  87. package/dist/types/plugin/create.d.ts +23 -0
  88. package/dist/types/plugin/index.d.ts +3 -0
  89. package/dist/types/plugin/profile.d.ts +2 -0
  90. package/dist/types/plugin/source.d.ts +1 -0
  91. package/dist/types/plugin/svg-component-template.d.cts +6 -0
  92. package/dist/types/router-client.d.ts +12 -0
  93. package/dist/types/router-handler.d.ts +13 -0
  94. package/dist/types/router-injection.d.ts +8 -0
  95. package/dist/types/router-server-cleanup.d.ts +3 -0
  96. package/dist/types/router-server-snapshot.d.ts +15 -0
  97. package/dist/types/router-server.d.ts +13 -0
  98. package/dist/types/router-snapshot.d.ts +14 -0
  99. package/dist/types/router.d.ts +30 -0
  100. package/dist/types/routes.d.ts +18 -0
  101. package/dist/types/server.d.ts +41 -0
  102. package/dist/types/typecheck.d.ts +31 -0
  103. package/package.json +211 -4
  104. package/src/bootstrap.ts +60 -0
  105. package/src/client.ts +485 -0
  106. package/src/entry-application.ts +72 -0
  107. package/src/entry-client.ts +80 -0
  108. package/src/entry-server.ts +142 -0
  109. package/src/federation-context.ts +53 -0
  110. package/src/federation.ts +158 -0
  111. package/src/i18n/I18nProvider.ts +56 -0
  112. package/src/i18n/LocalizedLink.ts +112 -0
  113. package/src/i18n/context.ts +12 -0
  114. package/src/i18n/index.ts +35 -0
  115. package/src/i18n/languageSync.ts +132 -0
  116. package/src/i18n/types.ts +36 -0
  117. package/src/i18n/useI18n.ts +119 -0
  118. package/src/index.ts +10 -0
  119. package/src/manifest.ts +253 -0
  120. package/src/plugin/compiler-manifest.cjs +178 -0
  121. package/src/plugin/compiler.ts +112 -0
  122. package/src/plugin/create.ts +272 -0
  123. package/src/plugin/index.ts +105 -0
  124. package/src/plugin/profile.ts +46 -0
  125. package/src/plugin/source.ts +16 -0
  126. package/src/plugin/svg-component-template.cjs +17 -0
  127. package/src/router-client.ts +144 -0
  128. package/src/router-handler.ts +182 -0
  129. package/src/router-injection.ts +145 -0
  130. package/src/router-server-cleanup.ts +11 -0
  131. package/src/router-server-snapshot.ts +564 -0
  132. package/src/router-server.ts +23 -0
  133. package/src/router-snapshot.ts +251 -0
  134. package/src/router.ts +192 -0
  135. package/src/routes.ts +263 -0
  136. package/src/server.ts +300 -0
  137. package/src/typecheck.ts +723 -0
@@ -0,0 +1,560 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import node_fs from "node:fs";
3
+ import node_path from "node:path";
4
+ import { SourceMap, shouldReportDiagnostics } from "@volar/language-core";
5
+ import { findNodeAtLocation, getNodeValue, parse, parseTree } from "jsonc-parser";
6
+ import { compileToVolarMappings } from "octane/compiler/volar";
7
+ import { version } from "typescript";
8
+ import { createVirtualFileSystem } from "typescript/unstable/fs";
9
+ import { API } from "typescript/unstable/sync";
10
+ const nativeExtension = /\.tsrx$/u;
11
+ const projectedExtension = /\.tsrx\.tsx$/u;
12
+ function typecheck_location(source, pos) {
13
+ const prefix = source.slice(0, pos);
14
+ const lines = prefix.split(/\r\n|\r|\n/u);
15
+ return {
16
+ line: lines.length,
17
+ column: (lines.at(-1)?.length ?? 0) + 1
18
+ };
19
+ }
20
+ function readFile(file) {
21
+ try {
22
+ return node_fs.readFileSync(file, 'utf8');
23
+ } catch (error) {
24
+ if (error instanceof Error && 'code' in error && ('ENOENT' === error.code || 'ENOTDIR' === error.code)) return;
25
+ throw error;
26
+ }
27
+ }
28
+ function projectConfig(source, fileName, discovery, roots) {
29
+ const errors = [];
30
+ const config = parseTree(source.replace(/^\uFEFF/u, ' '), errors, {
31
+ allowTrailingComma: true
32
+ });
33
+ if (errors.length || !config || 'object' !== config.type) return;
34
+ const edits = [];
35
+ const additions = [];
36
+ for (const field of [
37
+ 'files',
38
+ 'include',
39
+ 'exclude'
40
+ ]){
41
+ const array = findNodeAtLocation(config, [
42
+ field
43
+ ]);
44
+ if (roots) {
45
+ const content = JSON.stringify('files' === field ? roots : []);
46
+ if (array) {
47
+ if ('array' === array.type && (array.children ?? []).every((node)=>'string' === node.type)) edits.push({
48
+ offset: array.offset,
49
+ length: array.length,
50
+ content
51
+ });
52
+ } else additions.push(`${JSON.stringify(field)}:${content}`);
53
+ continue;
54
+ }
55
+ if (array?.type === 'array') for (const node of array.children ?? []){
56
+ const file = getNodeValue(node);
57
+ if ('string' != typeof file) continue;
58
+ const projected = 'files' === field || 'complete' === discovery ? nativeExtension.test(file) ? `${file}.tsx` : file : 'native' === discovery && /[.*?]/u.test(file.replaceAll('\\', '/').split('/').at(-1) ?? '') ? `${file.endsWith('/**') ? `${file}/*` : file}.tsx` : file;
59
+ if (projected !== file) edits.push({
60
+ offset: node.offset,
61
+ length: node.length,
62
+ content: JSON.stringify(projected)
63
+ });
64
+ }
65
+ }
66
+ if (additions.length) edits.push({
67
+ offset: config.offset + 1,
68
+ length: 0,
69
+ content: `${additions.join(',')}${config.children?.length ? ',' : ''}`
70
+ });
71
+ if (!edits.length) return;
72
+ const mappings = [];
73
+ let sourceOffset = 0;
74
+ let code = '';
75
+ for (const edit of edits.sort((left, right)=>left.offset - right.offset)){
76
+ const unchanged = source.slice(sourceOffset, edit.offset);
77
+ mappings.push({
78
+ sourceOffsets: [
79
+ sourceOffset
80
+ ],
81
+ generatedOffsets: [
82
+ code.length
83
+ ],
84
+ lengths: [
85
+ unchanged.length
86
+ ],
87
+ data: {
88
+ verification: true
89
+ }
90
+ });
91
+ code += unchanged;
92
+ mappings.push({
93
+ sourceOffsets: [
94
+ edit.offset
95
+ ],
96
+ generatedOffsets: [
97
+ code.length
98
+ ],
99
+ lengths: [
100
+ edit.length
101
+ ],
102
+ generatedLengths: [
103
+ edit.content.length
104
+ ],
105
+ data: {
106
+ verification: true
107
+ }
108
+ });
109
+ code += edit.content;
110
+ sourceOffset = edit.offset + edit.length;
111
+ }
112
+ mappings.push({
113
+ sourceOffsets: [
114
+ sourceOffset
115
+ ],
116
+ generatedOffsets: [
117
+ code.length
118
+ ],
119
+ lengths: [
120
+ source.length - sourceOffset
121
+ ],
122
+ data: {
123
+ verification: true
124
+ }
125
+ });
126
+ code += source.slice(sourceOffset);
127
+ return {
128
+ source,
129
+ fileName,
130
+ code,
131
+ map: new SourceMap(mappings)
132
+ };
133
+ }
134
+ function diagnosticText(diagnostic) {
135
+ return [
136
+ diagnostic.text,
137
+ ...diagnostic.messageChain?.map(diagnosticText) ?? []
138
+ ].join('\n');
139
+ }
140
+ function checkOctaneProject(options) {
141
+ if ('7.0.2' !== version) throw new Error(`Octane typechecking requires TypeScript 7.0.2; found ${version}`);
142
+ const cwd = node_path.resolve(options.cwd ?? process.cwd());
143
+ let project = node_path.resolve(cwd, options.project);
144
+ if (node_fs.existsSync(project) && node_fs.statSync(project).isDirectory()) project = node_path.join(project, 'tsconfig.json');
145
+ if (!node_fs.existsSync(project)) throw new Error(`Cannot find project ${project}`);
146
+ if (options.compilerOptions?.noEmit === false || options.compilerOptions?.noCheck === true || options.compilerOptions?.skipLibCheck === true || options.compilerOptions?.skipDefaultLibCheck === true) throw new Error('Octane typechecking requires noEmit, full checking, and library checking');
147
+ const effectiveConfig = node_path.join(node_path.dirname(project), `.octane-typecheck-${randomUUID()}.json`);
148
+ const authoredConfig = parse((readFile(project) ?? '').replace(/^\uFEFF/u, ' '), [], {
149
+ allowTrailingComma: true
150
+ });
151
+ const effectiveOptions = {
152
+ extends: project,
153
+ ...Array.isArray(authoredConfig?.references) ? {
154
+ references: authoredConfig.references
155
+ } : {},
156
+ compilerOptions: {
157
+ ...options.compilerOptions,
158
+ noEmit: true,
159
+ noCheck: false,
160
+ skipLibCheck: false,
161
+ skipDefaultLibCheck: false
162
+ }
163
+ };
164
+ const virtual = createVirtualFileSystem({
165
+ [effectiveConfig]: JSON.stringify(effectiveOptions)
166
+ });
167
+ const projections = new Map();
168
+ const configurations = new Map();
169
+ const configFiles = new Set([
170
+ project
171
+ ]);
172
+ const referencedConfigs = new Set([
173
+ project
174
+ ]);
175
+ const referenceRoots = new Map();
176
+ let discovery = 'ordinary';
177
+ function authoredName(file) {
178
+ if (!projectedExtension.test(file)) return file;
179
+ const authored = file.slice(0, -4);
180
+ if (!node_fs.existsSync(authored)) return file;
181
+ if (node_fs.existsSync(file)) throw new Error(`Octane projection collision: ${authored} conflicts with physical ${file}`);
182
+ return authored;
183
+ }
184
+ function projection(file) {
185
+ const fileName = authoredName(file);
186
+ if (fileName === file) return;
187
+ const known = projections.get(file);
188
+ if (known) return known;
189
+ const source = readFile(fileName);
190
+ if (void 0 === source) return;
191
+ let compiled;
192
+ try {
193
+ compiled = compileToVolarMappings(source, fileName, {
194
+ loose: true
195
+ });
196
+ } catch (error) {
197
+ if (!(error instanceof SyntaxError)) throw error;
198
+ compiled = {
199
+ code: 'export {};',
200
+ mappings: [],
201
+ diagnostics: [],
202
+ errors: [
203
+ {
204
+ name: error.name,
205
+ message: error.message,
206
+ fileName,
207
+ type: 'fatal',
208
+ ...'pos' in error && 'number' == typeof error.pos ? {
209
+ pos: error.pos
210
+ } : {},
211
+ ...'end' in error && 'number' == typeof error.end ? {
212
+ end: error.end
213
+ } : {}
214
+ }
215
+ ]
216
+ };
217
+ }
218
+ const result = {
219
+ ...compiled,
220
+ source,
221
+ fileName,
222
+ map: new SourceMap(compiled.mappings)
223
+ };
224
+ projections.set(file, result);
225
+ virtual.writeFile?.(file, compiled.code);
226
+ return result;
227
+ }
228
+ const overlay = {
229
+ readFile (file) {
230
+ const content = virtual.readFile?.(file);
231
+ if (void 0 !== content) return content;
232
+ const compiled = projection(file);
233
+ if (compiled) return compiled.code;
234
+ if (file.endsWith('.json')) {
235
+ const source = readFile(file);
236
+ if (void 0 !== source) {
237
+ if (!configFiles.has(file) && ('complete' === discovery || 'package.json' === node_path.basename(file))) return source;
238
+ configFiles.add(file);
239
+ const configData = parse(source.replace(/^\uFEFF/u, ' '), [], {
240
+ allowTrailingComma: true
241
+ });
242
+ for (const reference of referencedConfigs.has(file) && Array.isArray(configData?.references) ? configData.references : []){
243
+ if ('string' != typeof reference?.path) continue;
244
+ const target = node_path.resolve(node_path.dirname(file), reference.path);
245
+ const referenceFile = target.endsWith('.json') ? target : node_path.join(target, 'tsconfig.json');
246
+ configFiles.add(referenceFile);
247
+ referencedConfigs.add(referenceFile);
248
+ }
249
+ const roots = 'complete' === discovery ? referenceRoots.get(file) : void 0;
250
+ const config = projectConfig(source, file, discovery, roots ? [
251
+ ...roots
252
+ ] : void 0);
253
+ if (config) configurations.set(file, config);
254
+ else configurations.delete(file);
255
+ return config?.code ?? source;
256
+ }
257
+ }
258
+ },
259
+ fileExists (file) {
260
+ if (virtual.fileExists?.(file)) return true;
261
+ if (authoredName(file) !== file) return true;
262
+ },
263
+ directoryExists (directory) {
264
+ return virtual.directoryExists?.(directory) || void 0;
265
+ },
266
+ getAccessibleEntries (directory) {
267
+ const files = new Set(virtual.getAccessibleEntries?.(directory)?.files);
268
+ const directories = new Set(virtual.getAccessibleEntries?.(directory)?.directories);
269
+ try {
270
+ for (const entry of node_fs.readdirSync(directory, {
271
+ withFileTypes: true
272
+ })){
273
+ let isDirectory = entry.isDirectory();
274
+ if (entry.isSymbolicLink()) try {
275
+ isDirectory = node_fs.statSync(node_path.join(directory, entry.name)).isDirectory();
276
+ } catch (error) {
277
+ if (error instanceof Error && 'code' in error && ('ENOENT' === error.code || 'ENOTDIR' === error.code)) continue;
278
+ throw error;
279
+ }
280
+ if (isDirectory) directories.add(entry.name);
281
+ else {
282
+ files.add(entry.name);
283
+ if (nativeExtension.test(entry.name)) {
284
+ const projected = node_path.join(directory, `${entry.name}.tsx`);
285
+ authoredName(projected);
286
+ files.add(`${entry.name}.tsx`);
287
+ }
288
+ }
289
+ }
290
+ } catch (error) {
291
+ if (!(error instanceof Error && 'code' in error && ('ENOENT' === error.code || 'ENOTDIR' === error.code))) throw error;
292
+ }
293
+ return {
294
+ files: [
295
+ ...files
296
+ ].filter((file)=>'ordinary' !== discovery || authoredName(node_path.join(directory, file)) === node_path.join(directory, file)).sort(),
297
+ directories: [
298
+ ...directories
299
+ ].sort()
300
+ };
301
+ },
302
+ realpath (file) {
303
+ const authored = authoredName(file);
304
+ if (authored !== file) try {
305
+ return `${node_fs.realpathSync(authored)}.tsx`;
306
+ } catch {
307
+ return;
308
+ }
309
+ return virtual.fileExists?.(file) ? file : void 0;
310
+ }
311
+ };
312
+ const roots = new Set();
313
+ for (const mode of [
314
+ 'ordinary',
315
+ 'native'
316
+ ]){
317
+ discovery = mode;
318
+ const parser = new API({
319
+ cwd,
320
+ fs: overlay
321
+ });
322
+ try {
323
+ for (const file of parser.parseConfigFile(effectiveConfig).fileNames)if ('ordinary' === mode || authoredName(file) !== file) roots.add(file);
324
+ const parsedReferences = new Set([
325
+ project
326
+ ]);
327
+ for (const reference of referencedConfigs){
328
+ if (parsedReferences.has(reference)) continue;
329
+ parsedReferences.add(reference);
330
+ const selected = referenceRoots.get(reference) ?? new Set();
331
+ referenceRoots.set(reference, selected);
332
+ for (const file of parser.parseConfigFile(reference).fileNames)if ('ordinary' === mode || authoredName(file) !== file) selected.add(file);
333
+ }
334
+ } finally{
335
+ parser.close();
336
+ }
337
+ }
338
+ discovery = 'complete';
339
+ virtual.writeFile?.(effectiveConfig, JSON.stringify({
340
+ ...effectiveOptions,
341
+ files: [
342
+ ...roots
343
+ ],
344
+ include: [],
345
+ exclude: []
346
+ }));
347
+ const api = new API({
348
+ cwd,
349
+ fs: overlay
350
+ });
351
+ try {
352
+ const snapshot = api.updateSnapshot({
353
+ openProjects: [
354
+ effectiveConfig
355
+ ],
356
+ openFiles: [
357
+ ...roots
358
+ ]
359
+ });
360
+ const program = snapshot.getProject(effectiveConfig)?.program;
361
+ if (!program) throw new Error(`Native TypeScript did not load project ${project}`);
362
+ function remap(diagnostic) {
363
+ const relatedInformation = diagnostic.relatedInformation?.flatMap((info)=>{
364
+ const mapped = remap(info);
365
+ return mapped ? [
366
+ mapped
367
+ ] : [];
368
+ });
369
+ const text = diagnosticText(diagnostic);
370
+ const compiled = diagnostic.fileName ? projections.get(diagnostic.fileName) ?? configurations.get(diagnostic.fileName) : void 0;
371
+ let pos = diagnostic.pos;
372
+ let end = diagnostic.end;
373
+ let origin = "typescript";
374
+ let message = text;
375
+ if (compiled) {
376
+ const ranges = compiled.map.toSourceRange(pos, end, true, (info)=>shouldReportDiagnostics(info, void 0, diagnostic.code));
377
+ const range = ranges.next().value;
378
+ if (range) [pos, end] = range;
379
+ else {
380
+ if (!compiled.map.toSourceRange(pos, end, true).next().done) return;
381
+ origin = 'projection';
382
+ message = `Cannot map native TS${diagnostic.code} at generated offsets ${pos}-${end}: ${text}`;
383
+ pos = 0;
384
+ end = 0;
385
+ }
386
+ }
387
+ const fileName = compiled?.fileName ?? (diagnostic.fileName === effectiveConfig ? void 0 : diagnostic.fileName);
388
+ const source = compiled?.source ?? (fileName ? readFile(fileName) : void 0);
389
+ return {
390
+ ...fileName ? {
391
+ fileName
392
+ } : {},
393
+ pos,
394
+ end,
395
+ ...void 0 !== source ? typecheck_location(source, pos) : {},
396
+ code: diagnostic.code,
397
+ category: 'projection' === origin || 1 === diagnostic.category ? 'error' : 0 === diagnostic.category ? 'warning' : 'message',
398
+ text: message,
399
+ origin,
400
+ ...relatedInformation?.length ? {
401
+ relatedInformation
402
+ } : {}
403
+ };
404
+ }
405
+ const diagnostics = [
406
+ ...program.getConfigFileParsingDiagnostics(),
407
+ ...program.getProgramDiagnostics(),
408
+ ...program.getGlobalDiagnostics(),
409
+ ...program.getSyntacticDiagnostics(),
410
+ ...program.getBindDiagnostics(),
411
+ ...program.getSemanticDiagnostics()
412
+ ].flatMap((diagnostic)=>{
413
+ const mapped = remap(diagnostic);
414
+ return mapped ? [
415
+ mapped
416
+ ] : [];
417
+ });
418
+ const nativeFiles = program.getSourceFileNames();
419
+ for (const file of nativeFiles){
420
+ const compiled = projections.get(file);
421
+ if (compiled) {
422
+ for (const diagnostic of compiled.diagnostics)diagnostics.push({
423
+ fileName: compiled.fileName,
424
+ pos: diagnostic.start.offset,
425
+ end: diagnostic.end.offset,
426
+ ...typecheck_location(compiled.source, diagnostic.start.offset),
427
+ code: diagnostic.code,
428
+ category: 'error' === diagnostic.severity ? 'error' : 'warning' === diagnostic.severity ? 'warning' : 'message',
429
+ text: diagnostic.message,
430
+ origin: 'octane'
431
+ });
432
+ for (const error of compiled.errors){
433
+ const pos = error.pos ?? 0;
434
+ diagnostics.push({
435
+ fileName: compiled.fileName,
436
+ pos,
437
+ end: error.end ?? pos,
438
+ ...typecheck_location(compiled.source, pos),
439
+ code: 'OCTANE_PARSE',
440
+ category: 'error',
441
+ text: error.message,
442
+ origin: 'octane'
443
+ });
444
+ }
445
+ }
446
+ }
447
+ const unique = new Map(diagnostics.map((diagnostic)=>[
448
+ JSON.stringify(diagnostic),
449
+ diagnostic
450
+ ]));
451
+ return {
452
+ compilerVersion: version,
453
+ files: [
454
+ ...new Set(nativeFiles.map((file)=>projections.get(file)?.fileName ?? file))
455
+ ].sort(),
456
+ diagnostics: [
457
+ ...unique.values()
458
+ ].sort((left, right)=>(left.fileName ?? '').localeCompare(right.fileName ?? '') || left.pos - right.pos || String(left.code).localeCompare(String(right.code)))
459
+ };
460
+ } finally{
461
+ api.close();
462
+ }
463
+ }
464
+ function formatOctaneDiagnostic(diagnostic, cwd = process.cwd()) {
465
+ const file = diagnostic.fileName ? `${node_path.relative(cwd, diagnostic.fileName)}(${diagnostic.line ?? 1},${diagnostic.column ?? 1}): ` : '';
466
+ const code = 'number' == typeof diagnostic.code ? `TS${diagnostic.code}` : diagnostic.code;
467
+ const related = diagnostic.relatedInformation?.map((info)=>` ${formatOctaneDiagnostic(info, cwd)}`).join('\n');
468
+ return `${file}${diagnostic.category} ${code}: ${diagnostic.text}${related ? `\n${related}` : ''}`;
469
+ }
470
+ const booleanOptions = new Set([
471
+ 'strict',
472
+ 'isolatedModules',
473
+ 'verbatimModuleSyntax',
474
+ 'allowImportingTsExtensions',
475
+ 'allowJs',
476
+ 'esModuleInterop',
477
+ 'noUncheckedIndexedAccess',
478
+ 'exactOptionalPropertyTypes',
479
+ 'noImplicitOverride',
480
+ 'noFallthroughCasesInSwitch',
481
+ 'noPropertyAccessFromIndexSignature',
482
+ 'noImplicitReturns',
483
+ 'resolveJsonModule',
484
+ 'strictNullChecks',
485
+ 'strictFunctionTypes',
486
+ 'strictBindCallApply',
487
+ 'strictPropertyInitialization',
488
+ 'noImplicitAny',
489
+ 'noImplicitThis',
490
+ 'useUnknownInCatchVariables',
491
+ 'alwaysStrict'
492
+ ]);
493
+ const stringOptions = new Set([
494
+ 'target',
495
+ 'module',
496
+ 'moduleResolution',
497
+ 'moduleDetection',
498
+ 'jsx',
499
+ 'jsxImportSource'
500
+ ]);
501
+ function runOctaneTypecheck(argv, io = {}) {
502
+ const stdout = io.stdout ?? ((text)=>process.stdout.write(text));
503
+ const stderr = io.stderr ?? ((text)=>process.stderr.write(text));
504
+ try {
505
+ let project = 'tsconfig.json';
506
+ let listFiles = false;
507
+ const compilerOptions = {};
508
+ for(let index = 0; index < argv.length; index++){
509
+ const argument = argv[index];
510
+ if ('--version' === argument || '-v' === argument) {
511
+ stdout(`Version ${version}\n`);
512
+ return 0;
513
+ }
514
+ if ('--help' === argument || '-h' === argument) {
515
+ stdout('octane-tsc --project <tsconfig.json> [--noEmit] [--strict]\n');
516
+ return 0;
517
+ }
518
+ if ('--project' === argument || '-p' === argument) {
519
+ const value = argv[++index];
520
+ if (!value || value.startsWith('-')) throw new Error('--project requires a configuration path');
521
+ project = value;
522
+ continue;
523
+ }
524
+ if (!argument?.startsWith('--')) throw new Error(`Unsupported Octane typecheck argument ${argument}`);
525
+ const name = argument.slice(2);
526
+ if (booleanOptions.has(name) || [
527
+ 'noEmit',
528
+ 'noCheck',
529
+ 'skipLibCheck',
530
+ 'skipDefaultLibCheck',
531
+ 'pretty',
532
+ 'listFiles',
533
+ 'explainFiles'
534
+ ].includes(name)) {
535
+ const explicit = argv[index + 1];
536
+ const value = 'true' === explicit || 'false' === explicit ? 'true' === argv[++index] : true;
537
+ if ('noEmit' === name && !value || ('noCheck' === name || 'skipLibCheck' === name || 'skipDefaultLibCheck' === name) && value) throw new Error(`--${name} ${value} is incompatible with full Octane typechecking`);
538
+ if ('listFiles' === name || 'explainFiles' === name) listFiles ||= value;
539
+ else if ('pretty' !== name) compilerOptions[name] = value;
540
+ } else if (stringOptions.has(name) || 'lib' === name || 'types' === name) {
541
+ const value = argv[++index];
542
+ if (!value || value.startsWith('-')) throw new Error(`--${name} requires a value`);
543
+ compilerOptions[name] = 'lib' === name || 'types' === name ? value.split(',') : value;
544
+ } else throw new Error(`Unsupported Octane typecheck option --${name}`);
545
+ }
546
+ const cwd = node_path.resolve(io.cwd ?? process.cwd());
547
+ const result = checkOctaneProject({
548
+ project,
549
+ cwd,
550
+ compilerOptions
551
+ });
552
+ for (const diagnostic of result.diagnostics)stdout(`${formatOctaneDiagnostic(diagnostic, cwd)}\n`);
553
+ if (listFiles) for (const file of result.files)stdout(`${file}\n`);
554
+ return result.diagnostics.some((diagnostic)=>'error' === diagnostic.category) ? 1 : 0;
555
+ } catch (error) {
556
+ stderr(`${error instanceof Error ? error.message : String(error)}\n`);
557
+ return 1;
558
+ }
559
+ }
560
+ export { checkOctaneProject, formatOctaneDiagnostic, runOctaneTypecheck };
@@ -0,0 +1,10 @@
1
+ import { type DocumentBootstrap } from '@modern-js/renderer-core/document';
2
+ import { type RendererIdentity } from '@modern-js/renderer-core/identity';
3
+ export interface OctaneDocumentBootstrap extends DocumentBootstrap {
4
+ /** Actual native client compilation hash, separate from application identity. */
5
+ readonly nativeHydrationBuildId: string;
6
+ }
7
+ export declare function assertNativeHydrationBuildId(value: unknown): asserts value is string;
8
+ export declare function assertOctaneIdentity(identity: RendererIdentity): void;
9
+ /** Read the server's bootstrap and require this exact native client build. */
10
+ export declare function readOctaneDocumentBootstrap(document: Document, expectedIdentity: RendererIdentity, expectedNativeHydrationBuildId?: string): OctaneDocumentBootstrap;
@@ -0,0 +1,36 @@
1
+ import type { NativeFederationBinding } from '@modern-js/renderer-core/federation';
2
+ import { type RendererIdentity } from '@modern-js/renderer-core/identity';
3
+ import { type ComponentBody, type Root, type RootContainer, type RootOptions } from 'octane';
4
+ export type { OctaneDocumentBootstrap } from './bootstrap';
5
+ export { readOctaneDocumentBootstrap } from './bootstrap';
6
+ export interface OctaneApplicationModule {
7
+ readonly default: ComponentBody;
8
+ readonly props?: Record<string, unknown>;
9
+ /** Request-independent resources owned by this browser application module. */
10
+ readonly dispose?: () => void;
11
+ }
12
+ export interface OctaneApplicationHandle {
13
+ readonly root: Root;
14
+ readonly identity: Readonly<RendererIdentity>;
15
+ update(application: OctaneApplicationModule): void;
16
+ dispose(): void;
17
+ }
18
+ export interface OctaneApplicationOptions {
19
+ readonly container: Exclude<RootContainer, Document>;
20
+ readonly identity: RendererIdentity;
21
+ readonly nativeHydrationBuildId: string;
22
+ /** Cancels startup ownership and retires an active application. */
23
+ readonly signal?: AbortSignal;
24
+ /** Hydration installs the native signal bridge before invoking this importer. */
25
+ readonly load: () => Promise<OctaneApplicationModule>;
26
+ readonly options?: Omit<RootOptions, 'signalOwner'>;
27
+ /** This browser compilation's native Module Federation runtime. */
28
+ readonly federation?: NativeFederationBinding;
29
+ }
30
+ export interface OctaneHydrationOptions extends OctaneApplicationOptions {
31
+ readonly documentIdentity: RendererIdentity;
32
+ readonly documentNativeHydrationBuildId: string;
33
+ readonly documentId: string;
34
+ }
35
+ export declare function mountOctaneApplication(input: OctaneApplicationOptions): Promise<OctaneApplicationHandle>;
36
+ export declare function hydrateOctaneApplication(input: OctaneHydrationOptions): Promise<OctaneApplicationHandle>;
@@ -0,0 +1,19 @@
1
+ import type { LocalisedUrlsOption } from '@modern-js/i18n-runtime-extensions/paths';
2
+ import type { NativeI18nView } from '@modern-js/renderer-core/entry-client';
3
+ import type { NativeRouterFactory } from '@modern-js/renderer-core/router';
4
+ import { type AnyRoute, type AnyRouter } from '@octanejs/tanstack-router';
5
+ import { type ComponentBody } from 'octane';
6
+ export type OctaneI18nView = NativeI18nView<unknown, LocalisedUrlsOption>;
7
+ /** Wrap a component entry in its request's or document's i18n provider. */
8
+ export declare function componentView(component: unknown, i18n?: OctaneI18nView): ComponentBody;
9
+ /** The Octane route tree and router of a generated entry. */
10
+ export declare const octaneRouterFactory: NativeRouterFactory<AnyRoute, AnyRouter>;
11
+ interface LocalizedRouterProps {
12
+ readonly router: AnyRouter;
13
+ readonly i18n: OctaneI18nView;
14
+ }
15
+ /** Wrap a router root in the request's or document's i18n provider. */
16
+ export declare function localizedRouterRoot(Root: ComponentBody<{
17
+ router: AnyRouter;
18
+ }>): ComponentBody<LocalizedRouterProps>;
19
+ export {};
@@ -0,0 +1,8 @@
1
+ import type { LocalisedUrlsOption } from '@modern-js/i18n-runtime-extensions/paths';
2
+ import { type NativeClientEntryOptions, type NativeI18nInstance } from '@modern-js/renderer-core/entry-client';
3
+ export interface OctaneClientEntryOptions extends NativeClientEntryOptions<NativeI18nInstance, LocalisedUrlsOption> {
4
+ /** The native client compilation hash, `__webpack_hash__`. */
5
+ readonly nativeHydrationBuildId: string;
6
+ }
7
+ /** Start a generated Octane browser entry: mount, or hydrate the server document. */
8
+ export declare function startNativeClient(options: OctaneClientEntryOptions): void;
@@ -0,0 +1,11 @@
1
+ import type { LocalisedUrlsOption } from '@modern-js/i18n-runtime-extensions/paths';
2
+ import { type NativeI18nInstance, type NativeServerEntry, type NativeServerEntryOptions } from '@modern-js/renderer-core/entry-server';
3
+ import type { ResponsePolicy } from '@modern-js/renderer-core/session';
4
+ /**
5
+ * The loader projection strips representation fields; the ones an Octane route
6
+ * declares for the document itself are kept, as Solid document headers are.
7
+ */
8
+ export declare function withOctaneDocumentFields(policy: ResponsePolicy, responseHeaders: Headers): ResponsePolicy;
9
+ export type OctaneServerEntryOptions = NativeServerEntryOptions<NativeI18nInstance, LocalisedUrlsOption>;
10
+ /** The native transport handlers of a generated Octane server entry. */
11
+ export declare function createNativeServerEntry(options: OctaneServerEntryOptions): NativeServerEntry;
@@ -0,0 +1,28 @@
1
+ import { type FederationInstance, type NativeFederationBinding } from '@modern-js/renderer-core/federation';
2
+ import { type ComponentBody } from 'octane';
3
+ /** One application owns its host runtime; each response owns its render scope. */
4
+ export interface OctaneFederationScope {
5
+ readonly instance: FederationInstance | undefined;
6
+ readonly server: boolean;
7
+ readonly nonce?: string;
8
+ }
9
+ export declare const FederationContext: import("octane").Context<OctaneFederationScope | null>;
10
+ export declare function createFederationScope(binding: NativeFederationBinding | undefined, server: boolean, nonce?: string): OctaneFederationScope;
11
+ export declare function FederationRoot(props: {
12
+ readonly scope: OctaneFederationScope;
13
+ readonly children?: unknown;
14
+ }): import("octane").ElementDescriptor<{
15
+ value: OctaneFederationScope;
16
+ children: unknown;
17
+ }>;
18
+ /** A stable root component retains native state when its application updates. */
19
+ export declare function FederationApplication(props: {
20
+ readonly scope: OctaneFederationScope;
21
+ readonly application: {
22
+ readonly default: ComponentBody;
23
+ readonly props?: unknown;
24
+ };
25
+ }): import("octane").ElementDescriptor<{
26
+ scope: OctaneFederationScope;
27
+ children: import("octane").ElementDescriptor<unknown>;
28
+ }>;