arcane-os 0.1.0-dev.5 → 0.1.0
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/browser-runtime/ARCANE_SDK_BROWSER_RELEASE.json +86 -0
- package/browser-runtime/dependencies/event-pubsub/index.js +141 -0
- package/browser-runtime/dependencies/event-pubsub/licence +21 -0
- package/browser-runtime/dependencies/event-pubsub/package.json +59 -0
- package/browser-runtime/dependencies/strong-type/index.js +1151 -0
- package/browser-runtime/dependencies/strong-type/licence +21 -0
- package/browser-runtime/dependencies/strong-type/package.json +61 -0
- package/browser-runtime/dom-event-instrumentation.mjs +594 -0
- package/browser-runtime/event-manager.mjs +1342 -0
- package/docs/publishing.md +52 -59
- package/docs/reference/event-manager.md +5 -5
- package/docs/work-amplification.md +4 -3
- package/package.json +11 -7
- package/runtime/ARCANE_RUNTIME_RELEASE.json +1 -1
- package/schemas/arcane-lock.schema.json +86 -1
- package/src/cli/main.mjs +5 -0
- package/src/dev-server.mjs +78 -34
- package/src/doctor.mjs +77 -3
- package/src/import-map.mjs +2328 -0
- package/src/packager/core.mjs +607 -29
- package/src/scaffold.mjs +122 -5
- package/src/sdk-browser-runtime.mjs +585 -0
- package/src/targets/index.mjs +31 -4
- package/src/templates/workspace-template.mjs +135 -23
- package/src/toolchain.mjs +288 -55
- package/src/workspace-operation-lock.mjs +716 -0
- package/src/workspace-runtime.mjs +841 -0
- package/src/workspace.mjs +286 -37
package/src/scaffold.mjs
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import {lstat,mkdir,readFile,readdir,writeFile} from 'node:fs/promises';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import {spawn} from 'node:child_process';
|
|
4
|
-
import {
|
|
4
|
+
import {verifyRuntime} from './runtime.mjs';
|
|
5
|
+
import {verifySdkBrowserRuntime} from './sdk-browser-runtime.mjs';
|
|
6
|
+
import {materializeWorkspaceRuntime} from './workspace-runtime.mjs';
|
|
7
|
+
import {generateImportMap} from './import-map.mjs';
|
|
8
|
+
import {withWorkspaceOperationLock} from './workspace-operation-lock.mjs';
|
|
5
9
|
import {SDK_NAME,SDK_VERSION,workspaceTemplate} from './templates/workspace-template.mjs';
|
|
6
10
|
import {inspectWorkspaceProfile} from './workspace.mjs';
|
|
7
11
|
import {parseSemver} from './packager/core.mjs';
|
|
@@ -259,6 +263,29 @@ async function writeMissingFiles(workspaceRoot,files,{signal,onEvent}){
|
|
|
259
263
|
return {createdFiles,skippedFiles};
|
|
260
264
|
}
|
|
261
265
|
|
|
266
|
+
async function assertExistingLockAdmission(workspaceRoot,files){
|
|
267
|
+
const expected=files.get('arcane.lock.json');
|
|
268
|
+
if(typeof expected!=='string')return;
|
|
269
|
+
const lockPath=path.join(workspaceRoot,'arcane.lock.json');
|
|
270
|
+
let info;
|
|
271
|
+
try{
|
|
272
|
+
info=await lstat(lockPath);
|
|
273
|
+
}catch(error){
|
|
274
|
+
if(error?.code==='ENOENT')return;
|
|
275
|
+
throw error;
|
|
276
|
+
}
|
|
277
|
+
if(info.isSymbolicLink()||!info.isFile()){
|
|
278
|
+
fail('Existing arcane.lock.json must be a real file.');
|
|
279
|
+
}
|
|
280
|
+
if(await readFile(lockPath,'utf8')!==expected){
|
|
281
|
+
fail(
|
|
282
|
+
'Existing arcane.lock.json does not match the authenticated SDK runtime '
|
|
283
|
+
+'admission. Remove or reconcile it before running arcane init; Arcane never '
|
|
284
|
+
+'overwrites a lock implicitly.'
|
|
285
|
+
);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
|
|
262
289
|
async function runGitInit(workspaceRoot,signal,onEvent){
|
|
263
290
|
throwIfAborted(signal);
|
|
264
291
|
await emit(onEvent,{type:'scaffold.git.started',command:'git init -b main'});
|
|
@@ -313,17 +340,54 @@ export async function createWorkspace({
|
|
|
313
340
|
const workspaceRoot=path.resolve(targetPath);
|
|
314
341
|
await emit(onEvent,{type:'scaffold.started',mode:'create',workspaceRoot,appId,target});
|
|
315
342
|
await assertCreateTarget(workspaceRoot);
|
|
316
|
-
const
|
|
343
|
+
const receipt=await withWorkspaceOperationLock({
|
|
344
|
+
workspaceRoot,
|
|
345
|
+
operation:'scaffold-create',
|
|
346
|
+
signal,
|
|
347
|
+
onEvent
|
|
348
|
+
},async workspaceOperationLease=>{
|
|
349
|
+
const runtimeReceipt=await verifyRuntime({signal,onEvent});
|
|
350
|
+
const sdkBrowserRuntimeReceipt=await verifySdkBrowserRuntime({signal,onEvent});
|
|
317
351
|
const template=workspaceTemplate({
|
|
318
352
|
appId,
|
|
319
353
|
displayName,
|
|
320
|
-
runtimeRelease,
|
|
354
|
+
runtimeRelease:runtimeReceipt,
|
|
355
|
+
sdkBrowserRuntimeRelease:sdkBrowserRuntimeReceipt,
|
|
321
356
|
target,
|
|
322
357
|
appIcon:await scaffoldIcon(target)
|
|
323
358
|
});
|
|
324
359
|
const result=await writeMissingFiles(workspaceRoot,template.files,{signal,onEvent});
|
|
360
|
+
const workspaceRuntimeReceipt=await materializeWorkspaceRuntime({
|
|
361
|
+
workspaceRoot,
|
|
362
|
+
runtimeRoot:runtimeReceipt.canonicalLocation,
|
|
363
|
+
runtimeReceipt,
|
|
364
|
+
browserRuntimeRoot:sdkBrowserRuntimeReceipt.canonicalLocation,
|
|
365
|
+
sdkBrowserRuntimeReceipt,
|
|
366
|
+
signal,
|
|
367
|
+
onEvent
|
|
368
|
+
});
|
|
369
|
+
const importMap=await generateImportMap({
|
|
370
|
+
workspaceRoot,
|
|
371
|
+
appId,
|
|
372
|
+
appRoot:path.join(workspaceRoot,'apps',appId),
|
|
373
|
+
workspaceRuntimeReceipt,
|
|
374
|
+
workspaceOperationLease,
|
|
375
|
+
signal,
|
|
376
|
+
onEvent
|
|
377
|
+
});
|
|
325
378
|
if(initializeGit)await runGitInit(workspaceRoot,signal,onEvent);
|
|
326
|
-
const receipt={
|
|
379
|
+
const receipt={
|
|
380
|
+
workspaceRoot,
|
|
381
|
+
appId,
|
|
382
|
+
displayName:template.name,
|
|
383
|
+
target,
|
|
384
|
+
...result,
|
|
385
|
+
workspaceRuntime:workspaceRuntimeReceipt,
|
|
386
|
+
importMap,
|
|
387
|
+
gitInitialized:Boolean(initializeGit)
|
|
388
|
+
};
|
|
389
|
+
return receipt;
|
|
390
|
+
});
|
|
327
391
|
await emit(onEvent,{type:'scaffold.completed',...receipt});
|
|
328
392
|
return receipt;
|
|
329
393
|
}
|
|
@@ -342,13 +406,28 @@ export async function initWorkspace({
|
|
|
342
406
|
const resolvedRoot=path.resolve(workspaceRoot);
|
|
343
407
|
await emit(onEvent,{type:'scaffold.started',mode:'init',workspaceRoot:resolvedRoot,appId,target});
|
|
344
408
|
await assertInitTarget(resolvedRoot);
|
|
409
|
+
const receipt=await withWorkspaceOperationLock({
|
|
410
|
+
workspaceRoot:resolvedRoot,
|
|
411
|
+
operation:'scaffold-init',
|
|
412
|
+
signal,
|
|
413
|
+
onEvent
|
|
414
|
+
},async workspaceOperationLease=>{
|
|
345
415
|
const profile=await existingWorkspaceProfile(resolvedRoot);
|
|
346
416
|
const workspaceMode=profile?.workspaceMode??'external';
|
|
417
|
+
const legacyIntegrated=workspaceMode==='integrated'
|
|
418
|
+
&&profile.config.browserRuntimeLayout==='integrated-legacy';
|
|
419
|
+
const runtimeReceipt=workspaceMode==='external'
|
|
420
|
+
?await verifyRuntime({signal,onEvent})
|
|
421
|
+
:null;
|
|
422
|
+
const sdkBrowserRuntimeReceipt=workspaceMode==='external'
|
|
423
|
+
?await verifySdkBrowserRuntime({signal,onEvent})
|
|
424
|
+
:null;
|
|
347
425
|
const template=workspaceMode==='integrated'
|
|
348
426
|
?workspaceTemplate({
|
|
349
427
|
appId,
|
|
350
428
|
displayName,
|
|
351
429
|
appOnly:true,
|
|
430
|
+
namedImports:!legacyIntegrated,
|
|
352
431
|
minimumCoreVersion:await integratedCoreVersion(resolvedRoot),
|
|
353
432
|
target,
|
|
354
433
|
appIcon:await scaffoldIcon(target)
|
|
@@ -356,15 +435,49 @@ export async function initWorkspace({
|
|
|
356
435
|
:workspaceTemplate({
|
|
357
436
|
appId,
|
|
358
437
|
displayName,
|
|
359
|
-
runtimeRelease:
|
|
438
|
+
runtimeRelease:runtimeReceipt,
|
|
439
|
+
sdkBrowserRuntimeRelease:sdkBrowserRuntimeReceipt,
|
|
360
440
|
target,
|
|
361
441
|
appIcon:await scaffoldIcon(target)
|
|
362
442
|
});
|
|
363
443
|
const packagePlan=workspaceMode==='integrated'
|
|
364
444
|
?Object.freeze({exists:true,updated:false})
|
|
365
445
|
:await prepareExistingPackage(resolvedRoot,template.files);
|
|
446
|
+
if(workspaceMode==='external'){
|
|
447
|
+
await assertExistingLockAdmission(resolvedRoot,template.files);
|
|
448
|
+
}
|
|
366
449
|
const result=await writeMissingFiles(resolvedRoot,template.files,{signal,onEvent});
|
|
367
450
|
const packageUpdated=await applyPackageMerge(resolvedRoot,packagePlan,{signal,onEvent});
|
|
451
|
+
const workspaceRuntimeReceipt=workspaceMode==='external'
|
|
452
|
+
?await materializeWorkspaceRuntime({
|
|
453
|
+
workspaceRoot:resolvedRoot,
|
|
454
|
+
runtimeRoot:runtimeReceipt.canonicalLocation,
|
|
455
|
+
runtimeReceipt,
|
|
456
|
+
browserRuntimeRoot:sdkBrowserRuntimeReceipt.canonicalLocation,
|
|
457
|
+
sdkBrowserRuntimeReceipt,
|
|
458
|
+
signal,
|
|
459
|
+
onEvent
|
|
460
|
+
})
|
|
461
|
+
:null;
|
|
462
|
+
const importMap=legacyIntegrated
|
|
463
|
+
?Object.freeze({
|
|
464
|
+
appId,
|
|
465
|
+
skipped:true,
|
|
466
|
+
compatibility:'integrated-legacy',
|
|
467
|
+
reason:'The canonical integrated Arcane OS root retains its physical two-route browser runtime.'
|
|
468
|
+
})
|
|
469
|
+
:await generateImportMap({
|
|
470
|
+
workspaceRoot:resolvedRoot,
|
|
471
|
+
appId,
|
|
472
|
+
appRoot:path.join(resolvedRoot,'apps',appId),
|
|
473
|
+
workspaceRuntimeReceipt,
|
|
474
|
+
workspaceOperationLease,
|
|
475
|
+
signal,
|
|
476
|
+
onEvent
|
|
477
|
+
});
|
|
478
|
+
if(legacyIntegrated){
|
|
479
|
+
await emit(onEvent,{type:'import-map.compatibility.skipped',...importMap});
|
|
480
|
+
}
|
|
368
481
|
const receipt={
|
|
369
482
|
workspaceRoot:resolvedRoot,
|
|
370
483
|
workspaceMode,
|
|
@@ -373,8 +486,12 @@ export async function initWorkspace({
|
|
|
373
486
|
target,
|
|
374
487
|
...result,
|
|
375
488
|
packageUpdated,
|
|
489
|
+
workspaceRuntime:workspaceRuntimeReceipt,
|
|
490
|
+
importMap,
|
|
376
491
|
gitInitialized:false
|
|
377
492
|
};
|
|
493
|
+
return receipt;
|
|
494
|
+
});
|
|
378
495
|
await emit(onEvent,{type:'scaffold.completed',...receipt});
|
|
379
496
|
return receipt;
|
|
380
497
|
}
|