arcane-os 0.58.0 → 0.59.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/CHANGELOG.md +16 -0
- package/README.md +1 -1
- package/browser-runtime/core/client.mjs +1 -1
- package/docs/reference/README.md +4 -0
- package/docs/reference/availability-and-normalization.md +11 -7
- package/docs/reference/core-client.md +7 -0
- package/docs/reference/core-native-packaging.md +20 -8
- package/docs/reference/inventory/package-api.json +2 -2
- package/docs/reference/pwa.md +69 -2
- package/docs/reference/sdk-api.md +141 -0
- package/package.json +1 -1
- package/src/core/host.mjs +14 -5
- package/src/core/hosts/windows/ArcaneLauncher.cs +4 -1
- package/src/import-map.mjs +8 -4
- package/src/toolchain.mjs +41 -12
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.59.0
|
|
4
|
+
|
|
5
|
+
- Reconcile marked generated PWA references when a root application's PWA is
|
|
6
|
+
disabled. Add explicit `importMap({retireGeneratedPwa:true})` retirement for
|
|
7
|
+
the caller-confirmed generated root manifest reference and four standard PWA
|
|
8
|
+
output files. Ordinary disabled refresh preserves unmarked references and
|
|
9
|
+
files; authored content, unselected pages and browser storage remain intact.
|
|
10
|
+
- Forward the native host's selected state directory to Core service factories
|
|
11
|
+
as a launch-context default. Every explicit launch JSON field takes precedence
|
|
12
|
+
unchanged. Windows launcher source now supplies the same separate argument;
|
|
13
|
+
using that launcher correction requires the matching rebuilt host archive.
|
|
14
|
+
- Forward optional `Arcane.speech.synthesize(request, {signal})` cancellation
|
|
15
|
+
through the existing request lifetime, preserving complete payloads and the
|
|
16
|
+
180,000 ms default. Actual engine interruption remains service-owned; no new
|
|
17
|
+
speech engine, runtime dependency or data migration is introduced.
|
|
18
|
+
|
|
3
19
|
## 0.58.0
|
|
4
20
|
|
|
5
21
|
- Add native ONNX sessions through `arcane-os/local-ai/onnx` and browser Core
|
package/README.md
CHANGED
|
@@ -20,7 +20,7 @@ selected SDK projection or an explicit live SDK source mount. Both profiles
|
|
|
20
20
|
share the theme, packaging, event, cancellation,
|
|
21
21
|
and browser run contracts while retaining their selected application layout.
|
|
22
22
|
|
|
23
|
-
This checkout defines the `0.
|
|
23
|
+
This checkout defines the `0.59.0` SDK contract. Development applications declare
|
|
24
24
|
`arcane-os` as `latest` and retain their lockfile. Exact SDK pins begin when Roshi
|
|
25
25
|
designates a production build. Follow [Consumer updates](docs/consumer-updates.md)
|
|
26
26
|
to refresh and compare the installed SDK and lockfile with the published channel;
|
|
@@ -568,7 +568,7 @@ export function createCoreFacade(client){
|
|
|
568
568
|
remove:name=>invoke('environment.delete',{name})},
|
|
569
569
|
mail:{send:request=>invoke('mail.send',request??{},{timeoutMs:450000})},
|
|
570
570
|
speech:{status:()=>invoke('speech.status',{},{timeoutMs:10000}),
|
|
571
|
-
synthesize:request=>invoke('speech.synthesize',request??{},{timeoutMs:180000}),
|
|
571
|
+
synthesize:(request,options)=>invoke('speech.synthesize',request??{},{timeoutMs:180000,signal:options?.signal}),
|
|
572
572
|
transcribe:request=>invoke('speech.transcribe',request??{},{timeoutMs:180000})},
|
|
573
573
|
localAI:{status:()=>invoke('localai.status',{},{timeoutMs:15000}),
|
|
574
574
|
ensurePlatform:()=>invoke('localai.platform.ensure',{},long),recover:request=>invoke('localai.services.recover',request??{},long),
|
package/docs/reference/README.md
CHANGED
|
@@ -53,8 +53,12 @@ alone does not make bare module names resolve in a browser.
|
|
|
53
53
|
| Connect a browser to one Core transport | [Core browser client](core-client.md) |
|
|
54
54
|
| Compose native Core dispatch, service lifecycle, and stdio hosting | [Native Core runtime](core-runtime.md) |
|
|
55
55
|
| Run application-selected llama.cpp, Ollama or ONNX through Core | [Local AI through Core](local-ai.md) |
|
|
56
|
+
| Retain a Nemotron model and diarize caller-fed audio streams | [Native speaker diarization](diarization.md) |
|
|
57
|
+
| Persist application-selected preferences through Core | [Core preferences service](core-preferences.md) |
|
|
58
|
+
| Read complete selected Git text without changing a checkout | [Git text snapshots](git-text-snapshot.md) |
|
|
56
59
|
| Build an installed-SDK portable Core payload | [Portable Core packaging](core-native-packaging.md) |
|
|
57
60
|
| Build a Windows executable without an OS checkout | [Windows executable packaging](core-native-packaging.md#windows-executable) |
|
|
61
|
+
| Compose a Mac application with an architecture-matched host | [macOS application composition](core-native-packaging.md#macos-application-composition) |
|
|
58
62
|
| Subscribe to native events | [Arcane event reference](core/arcane-events.md) |
|
|
59
63
|
| Use provider-neutral AI lifecycle, chat, speech, persistence, or document context | [Normalized AI](#normalized-ai) |
|
|
60
64
|
| Choose a normalized typed browser decision surface | [Browser typed decisions](ai/browser-decisions.md) |
|
|
@@ -58,12 +58,12 @@ false when a probe throws; SDK branching continues through its owning error path
|
|
|
58
58
|
policy, package-owned model policy, platform support, and dependency readiness
|
|
59
59
|
are independent checks.
|
|
60
60
|
|
|
61
|
-
Windows x64
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
61
|
+
Windows x64 and macOS ARM64/x64 have SDK-owned provider and host composition
|
|
62
|
+
source. Their assembly paths require the matching numeric release's native
|
|
63
|
+
host archive; npm publication alone does not supply that archive or establish
|
|
64
|
+
platform execution. The macOS provider composes AppKit, WebKit and the shared
|
|
65
|
+
Node Core payload. Linux and Android retain their explicit checkout providers
|
|
66
|
+
where listed. See [native output and host requirements](core-native-packaging.md).
|
|
67
67
|
|
|
68
68
|
## Capability-first matrix
|
|
69
69
|
|
|
@@ -88,10 +88,14 @@ Source availability does not establish macOS compilation or execution.
|
|
|
88
88
|
| Read host identity, capabilities, storage, preferences, appearance, or platform state | `globalThis.Arcane` | **Cross-host** where the method is implemented and admitted | Promise behavior and `Arcane.Error` are normalized. Result fields are normalized unless the method explicitly documents a platform-dependent snapshot. |
|
|
89
89
|
| Connect browser code to an existing Core transport | `arcane-os/core/client` and `arcane-os/core/contracts` | **Browser / native WebView** with an admitted transport; explicit development HTTP remains opt-in | The reusable client owns `arcane/1` correlation, readiness, cancellation, events, facades, and complete native error fidelity. It supplies no service, policy, or host process. |
|
|
90
90
|
| Compose native Core services and framed stdio hosting | `arcane-os/core/runtime`, `arcane-os/core/stdio`, and `arcane-os/core/host` | **Node** on Windows, Linux, or macOS; the composing native host supplies its process and bridge | The SDK owns reusable dispatch, per-service lifecycle, request/service work ownership, cooperative cancellation, drain, and stdio framing. Product identity, policy, privileges, models, storage, and services remain host-owned. |
|
|
91
|
-
| Assemble a portable Core payload from the installed SDK | `arcane-os/native/portable-provider` | **Node**;
|
|
91
|
+
| Assemble a portable Core payload from the installed SDK | `arcane-os/native/portable-provider` | **Node**; explicit Windows, Linux or macOS platform selection | The provider copies the selected app, dependencies, installed SDK runtime, Core client/runtime, and explicit service composition into a non-executable directory. It uses no `arcaneRoot` by default and does not prove host behavior or supply a platform bridge. |
|
|
92
92
|
| Assemble and run a Windows executable | [`arcane-os/native/windows-provider`](core-native-packaging.md#windows-executable) | **Node** for assembly; Windows x64, .NET Framework 4.6.2+ and WebView2 for execution | Uses the installed SDK version's precompiled release asset and explicit app services. Complete diagnostics and accepted service work drain on run cancellation; no OS checkout or application-side native compiler is required. |
|
|
93
|
+
| Compose a macOS application bundle | [`arcane-os/native/macos-provider`](core-native-packaging.md#macos-application-composition) | **Node** assembly with matching host archive; matching Darwin ARM64/x64 for execution | Complete portable content stays in Resources. AppKit/WebKit launch, stable packaged origin, document activation and graceful Core drain remain host-owned. Source implementation is separate from a built/published host archive or actual Mac execution. |
|
|
94
|
+
| Persist application-owned Core preferences | [`arcane-os/core/preferences`](core-preferences.md) | **Node** Core service; renderer uses existing `Arcane.preferences` methods | Application-selected file and exact keys/JSON values, ordered in-process writes and service-lifetime drain. Unreadable storage remains untouched; saved values do not set operating-system preferences. |
|
|
95
|
+
| Read complete selected text from Git | [`createGitTextSnapshot`](git-text-snapshot.md) from `arcane-os` | **Node** with Git on Windows, Linux or macOS; Android requires host adaptation | One selected revision, complete UTF-8 content and independent result copies. A dedicated bare object cache leaves working checkouts untouched; shared refresh and drain own actual completion. |
|
|
93
96
|
| Use application-selected llama.cpp/Ollama through Core | [`arcane-os/core/local-ai`, `arcane-os/ai/core-local`](local-ai.md) | **Node** native service; **Browser / native WebView** provider through an explicit Core connection | Independent runtime/model lifecycle, complete streaming and cancellation. Official runtime preparation follows explicit app requirements; model selection and business policy stay app-owned. |
|
|
94
97
|
| Run native ONNX tensors | [`arcane-os/local-ai/onnx`, `arcane-os/ai/core-onnx`](local-ai.md#native-onnx-sessions) | **Node** Windows/Linux/macOS x64/arm64; **Browser / native WebView** through available Core | Explicit graph loading, retained workers and complete tensor outputs. Android requires host adaptation. Native calls can delay worker termination; cleanup observes actual exit. |
|
|
98
|
+
| Label speakers in caller-fed mono audio | [`arcane-os/diarization`, `arcane-os/core/diarization`](diarization.md) | **Node** with built helper, selected official NeMo libraries and Nemotron model; official CPU archives cover Windows x64 and Linux/macOS x64/arm64 | Independent retained streams, complete timed segments and optional probability frames. Generic labels are not personal identities or speech transcripts; cancellation and close observe native cleanup. Android needs host adaptation. |
|
|
95
99
|
| Use local AI without coupling app code to Ollama HTTP | `Arcane.localAI`, `Arcane.ai`, or `/arcane/modules/Ollama.js` | Primarily **Native**; Android exposes a narrower admitted inference projection | Admission, errors, and managed-operation events are normalized. Direct Ollama response envelopes remain **Provider-native**. |
|
|
96
100
|
| Use TWiN Cloud from the renderer profile | `/arcane/modules/AI.js` | **Cloud** from an allowed browser/native renderer | High-level chat behavior is normalized by the module. The TWiN access key authenticates remote LLM chat; raw provider diagnostics remain provider-specific. No automatic cloud fallback is inferred from local failure. |
|
|
97
101
|
| Send one TWiN Cloud request with an explicit key and model | `fetchRequest` from `arcane-os/ai/twin-cloud` | **Node** and **Browser**, using standard Fetch and a remote HTTPS provider | Keeps complete messages and returns the full parsed provider JSON. Rejected Fetch and HTTP 529 share three retries after 3000 ms; HTTP 429 overload retains unlimited three-second retries. Optional `onRetry` reports waiting/requesting phases without blocking recovery. Shared structured-output mapping and cancellation match browser TWiN transport. No browser profile, AI/user singleton, DBOPFS, or retained request history is created. |
|
|
@@ -77,6 +77,13 @@ The compatibility facade retains its operation-specific timeouts and streaming
|
|
|
77
77
|
callbacks. Streaming IDs and isolated-operation IDs are separate protocol
|
|
78
78
|
correlation fields alongside the supplied request fields.
|
|
79
79
|
|
|
80
|
+
`Arcane.speech.synthesize(request, {signal})` forwards the optional cancellation
|
|
81
|
+
signal through the same request lifetime. Existing one-argument calls retain
|
|
82
|
+
the 180,000 ms timeout and pass the complete request unchanged. A pre-aborted
|
|
83
|
+
signal sends no synthesis request; an in-flight abort sends `request.cancel`
|
|
84
|
+
and suppresses late responses. Actual synthesis interruption depends on the
|
|
85
|
+
registered speech service and its engine; the facade supplies no speech engine.
|
|
86
|
+
|
|
80
87
|
## Events and request lifetime
|
|
81
88
|
|
|
82
89
|
`events.on(name, listener)`, `once(name, listener)` and
|
|
@@ -212,10 +212,14 @@ details and [the client contract](core-client.md) for native bridge integration.
|
|
|
212
212
|
|
|
213
213
|
The generated Core entry accepts `--arcane-launch-config <path>`. The public
|
|
214
214
|
`readCoreLaunchContext({argv=process.argv.slice(2)}={})` function in
|
|
215
|
-
`arcane-os/core/host` reads that explicitly selected JSON object.
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
215
|
+
`arcane-os/core/host` reads that explicitly selected JSON object. A native host
|
|
216
|
+
can separately supply `--arcane-host-state-root <directory>` for the reader's
|
|
217
|
+
`stateRoot` default. Every field in the explicit JSON object takes precedence
|
|
218
|
+
unchanged, including an explicitly present `stateRoot` with a relative, null or
|
|
219
|
+
other application-owned value. With neither argument the reader returns `{}`.
|
|
220
|
+
Missing files, missing argument values and malformed JSON report their actual
|
|
221
|
+
errors; the reader does not search for configuration, resolve or validate the
|
|
222
|
+
state directory, rewrite the file or change the process environment.
|
|
219
223
|
|
|
220
224
|
The generated entry supplies an artifact-derived `appRoot` and then applies the
|
|
221
225
|
complete explicit launch context. Every service factory receives that same
|
|
@@ -224,7 +228,10 @@ launcher can supply the user's selected `workspaceRoot` and writable
|
|
|
224
228
|
`stateRoot` at launch instead of embedding this machine's paths in an app
|
|
225
229
|
package. The host owns those selections; the SDK does not choose a product's
|
|
226
230
|
workspace, namespace, saved preferences or models. JSON values and additional
|
|
227
|
-
application-owned fields remain unchanged
|
|
231
|
+
application-owned fields remain unchanged, including an app-selected
|
|
232
|
+
`preferencesFile`. The state directory supplies no preference filename and
|
|
233
|
+
triggers no stored-data discovery or migration. Linux and other composing hosts
|
|
234
|
+
may pass the same separate argument; the reader chooses no platform directory.
|
|
228
235
|
|
|
229
236
|
## Selected local-AI runtimes
|
|
230
237
|
|
|
@@ -305,8 +312,11 @@ Arcane.exe --arcane-launch-config path/to/launch.json
|
|
|
305
312
|
The complete JSON object reaches the service factories as their second
|
|
306
313
|
argument. A supplied `stateRoot` also owns the WebView2 profile and diagnostic
|
|
307
314
|
directory. Otherwise the launcher uses the current user's local application
|
|
308
|
-
data under `Arcane/<app-id>`.
|
|
309
|
-
|
|
315
|
+
data under `Arcane/<app-id>`. It forwards that actual host selection through
|
|
316
|
+
`--arcane-host-state-root`, so ordinary double-click startup supplies `stateRoot`
|
|
317
|
+
to every Core service factory. The complete explicit launch context still takes
|
|
318
|
+
precedence without rewriting its fields. The launcher does not invent an
|
|
319
|
+
application workspace. Relative launch-file paths resolve from the invocation's working
|
|
310
320
|
directory. `--close-on-stdin-eof` is an explicit process-owner option used by the
|
|
311
321
|
SDK runner; an ordinary double-clicked window closes through its own UI.
|
|
312
322
|
|
|
@@ -414,7 +424,9 @@ owner and published `node-http-server`, not a second HTTP implementation.
|
|
|
414
424
|
`context.stateRoot` takes precedence over the launcher's separate
|
|
415
425
|
`--arcane-host-state-root` argument. The launcher defaults to
|
|
416
426
|
`~/Library/Application Support/Arcane/<app-id>`; an explicitly supplied launch
|
|
417
|
-
file remains unchanged and is forwarded to Core. The
|
|
427
|
+
file remains unchanged and is forwarded to Core. The shared launch reader also
|
|
428
|
+
supplies that host default to every application service factory, with explicit
|
|
429
|
+
launch fields taking precedence. The first successful listener
|
|
418
430
|
stores its selected port in `packaged-web-origin.json`. Later launches reuse it;
|
|
419
431
|
a port conflict or unreadable saved record is reported without changing origins
|
|
420
432
|
or discarding stored state.
|
|
@@ -4175,10 +4175,10 @@
|
|
|
4175
4175
|
"entrypoints": ["arcane-os/core/host"],
|
|
4176
4176
|
"primaryImport": "arcane-os/core/host",
|
|
4177
4177
|
"group": "Native Core host composition",
|
|
4178
|
-
"summary": "Reads
|
|
4178
|
+
"summary": "Reads explicit launch JSON with the separately supplied native host stateRoot default for service launch context.",
|
|
4179
4179
|
"availability": "Node, including the selected external-entry SEA launcher",
|
|
4180
4180
|
"protocol": "Explicit launch arguments and JSON configuration",
|
|
4181
|
-
"normalization": "
|
|
4181
|
+
"normalization": "Optional --arcane-host-state-root <directory> supplies the stateRoot default; every explicit --arcane-launch-config JSON field takes precedence unchanged, including relative or null stateRoot and application-owned preferencesFile. Returns an empty record with neither argument; surfaces missing argument values, file and JSON failures; performs no directory selection, path resolution, configuration search, rewrite, migration or environment mutation"
|
|
4182
4182
|
},
|
|
4183
4183
|
{
|
|
4184
4184
|
"id": "core-host:startCoreHost",
|
package/docs/reference/pwa.md
CHANGED
|
@@ -94,14 +94,81 @@ packaging use that layout directly:
|
|
|
94
94
|
packaged installation ID remains `./`, and an explicit `manifest.id` remains
|
|
95
95
|
authoritative. An ID identifies the installation; it does not generate a
|
|
96
96
|
directory or a redirect.
|
|
97
|
-
- Authored resources follow their normal include/exclude selection.
|
|
98
|
-
|
|
97
|
+
- Authored resources follow their normal include/exclude selection. Ordinary
|
|
98
|
+
generation preserves existing files, stored application data, and worker caches.
|
|
99
|
+
Explicit retirement of confirmed generated source output is described below.
|
|
99
100
|
|
|
100
101
|
Generated and offline app files are committed. GitHub Actions consume those
|
|
101
102
|
committed files rather than generating them. Actual multi-app workspaces keep
|
|
102
103
|
their explicit `appsRoot: "apps"` layout. This source/package contract does not
|
|
103
104
|
establish any particular installed application's browser lifecycle.
|
|
104
105
|
|
|
106
|
+
### Disable source PWA generation and retire generated output
|
|
107
|
+
|
|
108
|
+
Set `package.pwa.enabled:false` in `arcane-app.json` (or `pwa.enabled:false` in
|
|
109
|
+
an authored schema-1 `arcane-package.json`), then run the public import-map
|
|
110
|
+
operation. For standalone `appsRoot:"."` applications, disabled refresh removes
|
|
111
|
+
active `data-arcane-pwa` registration scripts and matching manifest relationships
|
|
112
|
+
marked `data-arcane-manifest` from the selected application documents. Root source
|
|
113
|
+
generation marks only manifest links it newly inserts; it does not claim an
|
|
114
|
+
existing unmarked link as its own. A wholly omitted `pwa` record does not select
|
|
115
|
+
source retirement.
|
|
116
|
+
|
|
117
|
+
By default, unmarked manifest references and all existing PWA files remain in
|
|
118
|
+
place. This preserves authored resources that happen to use the standard names.
|
|
119
|
+
Older SDK source generation emitted an unmarked manifest link. When the
|
|
120
|
+
application owner has established that this link and the four standard root
|
|
121
|
+
outputs are SDK-generated, use the same public toolchain with an explicit
|
|
122
|
+
ownership declaration:
|
|
123
|
+
|
|
124
|
+
```js
|
|
125
|
+
import {createToolchain} from 'arcane-os';
|
|
126
|
+
|
|
127
|
+
const toolchain = createToolchain({workspaceRoot: process.cwd(), appId: 'my-app'});
|
|
128
|
+
await toolchain.importMap({retireGeneratedPwa: true});
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Before retirement, remove any explicit entries for these generated outputs from
|
|
132
|
+
the application's `package.include` selection. They are generated output, not
|
|
133
|
+
required source input; leaving a deleted file as a required input would make the
|
|
134
|
+
next inspection fail. Keep authored selection changes with the application
|
|
135
|
+
owner. Confirm that unselected documents or separately hosted pages do not still
|
|
136
|
+
need the retiring files; this operation does not rewrite those pages.
|
|
137
|
+
|
|
138
|
+
With PWA disabled, `retireGeneratedPwa:true` also removes selected-document
|
|
139
|
+
manifest relationships resolving to the root `arcane.webmanifest`, including
|
|
140
|
+
older unmarked generated links, and deletes exactly these confirmed generated
|
|
141
|
+
files at the application root:
|
|
142
|
+
|
|
143
|
+
- `arcane.webmanifest`
|
|
144
|
+
- `arcane-offline.json`
|
|
145
|
+
- `arcane-sw.js`
|
|
146
|
+
- `arcane-pwa.mjs`
|
|
147
|
+
|
|
148
|
+
The option is an application-owner declaration of generated ownership, not a
|
|
149
|
+
filename-based inference. Omit it when any listed file or matching manifest
|
|
150
|
+
reference is authored or its ownership is unknown. It is available through
|
|
151
|
+
`createToolchain().importMap()` and `executeOperation('import-map', options)`;
|
|
152
|
+
there is no new CLI flag. The ordinary CLI refresh performs marked-reference
|
|
153
|
+
retirement only. An enabled descriptor ignores this retirement option and
|
|
154
|
+
continues normal generation.
|
|
155
|
+
|
|
156
|
+
With the source selection updated, repeated retirement accepts already-absent
|
|
157
|
+
generated files. The
|
|
158
|
+
`import-map.root-files.completed` event reports the paths actually removed in
|
|
159
|
+
`retiredPwa`. Re-enabling PWA regenerates its normal root output and references.
|
|
160
|
+
The operation leaves other files (including a separate `manifest.json`), other
|
|
161
|
+
link relationships, inactive HTML, unselected documents, SDK mappings, and
|
|
162
|
+
application content unchanged. It never unregisters an already registered
|
|
163
|
+
service worker, clears caches, or changes browser saved data. Existing browser
|
|
164
|
+
registrations therefore keep their own lifecycle; source retirement is not a
|
|
165
|
+
claim that an installed browser PWA was removed. Package-output behavior below
|
|
166
|
+
is unchanged.
|
|
167
|
+
|
|
168
|
+
Reference updates finish before file removal begins. Cancellation or a file
|
|
169
|
+
error is reported without undoing earlier completed changes; a later call can
|
|
170
|
+
finish retirement. The operation does not claim an all-or-nothing transaction.
|
|
171
|
+
|
|
105
172
|
### Authored host root and app entry
|
|
106
173
|
|
|
107
174
|
An authored `index.html` at the source host root keeps `/` separate from the
|
|
@@ -58,6 +58,10 @@ runtime layouts.
|
|
|
58
58
|
| `arcane-os/core/stdio` | Framed Node stdio transport with graceful runtime drain. |
|
|
59
59
|
| `arcane-os/core/host` | Node-only reusable Core host lifecycle with explicitly supplied services. |
|
|
60
60
|
| `arcane-os/core/packaged-web` | Core-owned packaged web listener with a persisted loopback origin and ready/failure events. |
|
|
61
|
+
| `arcane-os/core/preferences` | Existing preference RPC methods with an application-selected file, ordered writes and owned drain. |
|
|
62
|
+
| `arcane-os/core/diarization` | Lazy native speaker-diarization service, explicit stream methods and lifecycle/result events. |
|
|
63
|
+
| `arcane-os/diarization` | Retained Nemotron model helper and independent caller-fed audio streams. |
|
|
64
|
+
| `arcane-os/diarization/build` | First-party helper compilation against explicitly installed NeMo-Speech.cpp libraries. |
|
|
61
65
|
| `arcane-os/core/local-ai` | Native llama.cpp, Ollama and ONNX Core service, model readiness, complete responses and owned lifecycle. See [local AI through Core](local-ai.md). |
|
|
62
66
|
| `arcane-os/local-ai` | Official runtime installation and native artifact bundling for selected llama.cpp/Ollama/ONNX requirements and NeMo libraries. |
|
|
63
67
|
| `arcane-os/local-ai/onnx` | Retained native ONNX worker sessions with explicit graph loading and complete tensor inference. |
|
|
@@ -389,6 +393,12 @@ The remaining data-only subpaths are eight JSON Schemas and package metadata.
|
|
|
389
393
|
| `arcaneNativeBuilderProvider` | singleton | `arcane-os/native/macos-provider` | macOS native provider | Node assembly; matching Darwin architecture and selected host asset |
|
|
390
394
|
| `arcaneNativeBuilderProvider default export` | singleton | `arcane-os/native/macos-provider` | macOS native provider | Node assembly; matching Darwin architecture and selected host asset |
|
|
391
395
|
| `createPackagedWebService()` | function | `arcane-os/core/packaged-web` | Native packaged web serving | Node Core lifetime; actual listener readiness before navigation |
|
|
396
|
+
| `createPreferencesService()` | function | `arcane-os/core/preferences` | Core preference persistence | Node Core runtime with an application-selected file |
|
|
397
|
+
| `createPreferencesService default export` | function | `arcane-os/core/preferences` | Core preference persistence | Same Core service factory |
|
|
398
|
+
| `createDiarization()` | function | `arcane-os/diarization` | Native speaker diarization | Node with a built helper, selected NeMo libraries and caller-selected model |
|
|
399
|
+
| `buildDiarizationHelper()` | function | `arcane-os/diarization/build` | Native speaker diarization | Node with installed CMake/C++17 toolchain and selected runtime |
|
|
400
|
+
| `createDiarizationService()` | function | `arcane-os/core/diarization` | Native speaker diarization | Node Core runtime with explicitly selected helper, runtime and model |
|
|
401
|
+
| `createDiarizationService default export` | function | `arcane-os/core/diarization` | Native speaker diarization | Same Core service factory |
|
|
392
402
|
| `createCoreLocalAIProvider()` | function | `arcane-os/ai/core-local` | Core local AI | Browser/native WebView with an available Core connection |
|
|
393
403
|
| `createLocalAIService()` | function | `arcane-os/core/local-ai` | Core local AI | Node with selected llama.cpp/Ollama/ONNX runtimes |
|
|
394
404
|
| `createONNXRuntime()` | function | `arcane-os/local-ai/onnx` | Core local AI | Node with prepared Microsoft ONNX runtime |
|
|
@@ -7415,6 +7425,137 @@ errors, with no silent new origin. Startup rejection belongs to the Core
|
|
|
7415
7425
|
and lifecycle completion. No application launch payload is rewritten, no model
|
|
7416
7426
|
is loaded, and the ordinary server's HTTPS default is unchanged.
|
|
7417
7427
|
|
|
7428
|
+
## createPreferencesService()
|
|
7429
|
+
|
|
7430
|
+
### Overview
|
|
7431
|
+
|
|
7432
|
+
Supplies the five existing `Arcane.preferences` methods using an application-selected
|
|
7433
|
+
JSON file. Construction performs no filesystem work. Preference names, defaults,
|
|
7434
|
+
schemas and writable location remain application-owned.
|
|
7435
|
+
|
|
7436
|
+
### Signature and result
|
|
7437
|
+
|
|
7438
|
+
```text
|
|
7439
|
+
createPreferencesService({file}={})
|
|
7440
|
+
```
|
|
7441
|
+
|
|
7442
|
+
Import from `arcane-os/core/preferences`. The returned Core service exposes
|
|
7443
|
+
`preferences.list/get/set/setMany/delete`, `drain()` and `dispose()`. Writes use
|
|
7444
|
+
`lifetime:'service'`, preserve complete JSON values and existing document metadata,
|
|
7445
|
+
and acknowledge after the new content is flushed and the selected file replaced.
|
|
7446
|
+
Operations selecting the same resolved filename share an ordered in-process queue.
|
|
7447
|
+
Unreadable or malformed files report their errors without being replaced; a missing
|
|
7448
|
+
file starts with empty entries. Unrepresentable JSON values fail before replacement.
|
|
7449
|
+
|
|
7450
|
+
```javascript
|
|
7451
|
+
import {createPreferencesService} from 'arcane-os/core/preferences';
|
|
7452
|
+
|
|
7453
|
+
const preferences = createPreferencesService({file: selectedPreferenceFile});
|
|
7454
|
+
```
|
|
7455
|
+
|
|
7456
|
+
Register the service with the existing Core owner. Its drain/dispose stops new
|
|
7457
|
+
acceptance, waits for accepted work and exposes failures; subsequent calls reject
|
|
7458
|
+
with `CORE_CLOSING`. See [method results, storage and service composition](core-preferences.md).
|
|
7459
|
+
|
|
7460
|
+
## createPreferencesService default export
|
|
7461
|
+
|
|
7462
|
+
The default export from `arcane-os/core/preferences` is the same
|
|
7463
|
+
`createPreferencesService` factory, with identical arguments, method results
|
|
7464
|
+
and lifecycle:
|
|
7465
|
+
|
|
7466
|
+
```javascript
|
|
7467
|
+
import createPreferencesService from 'arcane-os/core/preferences';
|
|
7468
|
+
```
|
|
7469
|
+
|
|
7470
|
+
## createDiarization()
|
|
7471
|
+
|
|
7472
|
+
### Overview
|
|
7473
|
+
|
|
7474
|
+
Retains one caller-selected Nemotron model in its first-party native helper and
|
|
7475
|
+
accepts independent mono-audio streams. Results contain generic timed speaker
|
|
7476
|
+
labels; they do not identify people or perform speech recognition.
|
|
7477
|
+
|
|
7478
|
+
### Signature and result
|
|
7479
|
+
|
|
7480
|
+
```text
|
|
7481
|
+
createDiarization({executable,modelPath,runtime,onEvent}={})
|
|
7482
|
+
```
|
|
7483
|
+
|
|
7484
|
+
Import from `arcane-os/diarization`. Supply absolute helper/model paths and the
|
|
7485
|
+
selected runtime's library locations. The returned owner starts the helper and
|
|
7486
|
+
exposes `ready`, `completion`, `current()`, replaying `subscribe()`,
|
|
7487
|
+
`openStream()`, `diarize()` and `close()`. Readiness resolves only after model
|
|
7488
|
+
loading. Each stream owns `push`, `finish`, `cancel`, `completion` and `current`;
|
|
7489
|
+
pushes preserve mono float32 input, use backpressure and return the latest timed
|
|
7490
|
+
segment snapshot. Caller callbacks may receive every probability frame.
|
|
7491
|
+
|
|
7492
|
+
```javascript
|
|
7493
|
+
import {createDiarization} from 'arcane-os/diarization';
|
|
7494
|
+
|
|
7495
|
+
const speakers = createDiarization({executable, modelPath, runtime});
|
|
7496
|
+
const result = await speakers.diarize({audio: monoSamples, sampleRate: 16000});
|
|
7497
|
+
await speakers.close();
|
|
7498
|
+
```
|
|
7499
|
+
|
|
7500
|
+
Load, callback, process and cleanup failures remain observable. Cancellation
|
|
7501
|
+
suppresses later results for its stream and closes it after accepted native
|
|
7502
|
+
commands; the C ABI supplies no immediate interrupt. Close drains owned work
|
|
7503
|
+
and observes helper exit. See [complete audio, callback and cancellation contracts](diarization.md).
|
|
7504
|
+
|
|
7505
|
+
## buildDiarizationHelper()
|
|
7506
|
+
|
|
7507
|
+
```text
|
|
7508
|
+
async buildDiarizationHelper({runtime,outputRoot,signal,onEvent}={})
|
|
7509
|
+
```
|
|
7510
|
+
|
|
7511
|
+
Import from `arcane-os/diarization/build`. Builds the first-party helper for the
|
|
7512
|
+
current host using installed CMake/C++17 tools and the selected runtime's
|
|
7513
|
+
`cmakeDirectory`. Returns `{platform,architecture,root,executable,diagnostics}`
|
|
7514
|
+
after configure, compile and install, retaining complete command diagnostics.
|
|
7515
|
+
Missing inputs or actual tool failures reject through the shared process owner;
|
|
7516
|
+
no compiler, model or runtime is downloaded by this function.
|
|
7517
|
+
|
|
7518
|
+
```javascript
|
|
7519
|
+
import {buildDiarizationHelper} from 'arcane-os/diarization/build';
|
|
7520
|
+
|
|
7521
|
+
const helper = await buildDiarizationHelper({runtime, outputRoot: helperDirectory});
|
|
7522
|
+
```
|
|
7523
|
+
|
|
7524
|
+
See [runtime preparation, helper placement and platform support](diarization.md#runtime-and-helper).
|
|
7525
|
+
|
|
7526
|
+
## createDiarizationService()
|
|
7527
|
+
|
|
7528
|
+
```text
|
|
7529
|
+
createDiarizationService(options={},launch={})
|
|
7530
|
+
```
|
|
7531
|
+
|
|
7532
|
+
Import from `arcane-os/core/diarization`. This synchronous `native.services`
|
|
7533
|
+
factory accepts `{executable,modelPath,runtime,onEvent}` and the native launch
|
|
7534
|
+
context. Relative executable/model paths use `workspaceRoot`, then `appRoot`,
|
|
7535
|
+
then the current directory. It supplies `diarization.status`, `diarization.load`,
|
|
7536
|
+
`diarization.open`, `diarization.push`, `diarization.finish`, `diarization.cancel`
|
|
7537
|
+
and `diarization.recording`, state/update/probability events and drain/dispose hooks.
|
|
7538
|
+
The first actual operation loads the model, independently of Core startup.
|
|
7539
|
+
|
|
7540
|
+
```javascript
|
|
7541
|
+
import {createDiarizationService} from 'arcane-os/core/diarization';
|
|
7542
|
+
|
|
7543
|
+
const service = createDiarizationService({executable, modelPath, runtime}, launch);
|
|
7544
|
+
```
|
|
7545
|
+
|
|
7546
|
+
Session audio has service lifetime and explicit cancellation; a recording's
|
|
7547
|
+
request cancellation closes only that recording. Complete float32 samples use
|
|
7548
|
+
the documented Core transport framing. See [inputs, results, events and lifetime](diarization.md#core-service).
|
|
7549
|
+
|
|
7550
|
+
## createDiarizationService default export
|
|
7551
|
+
|
|
7552
|
+
The default binding from `arcane-os/core/diarization` is exactly the named
|
|
7553
|
+
`createDiarizationService` factory, with the same selection and service lifecycle:
|
|
7554
|
+
|
|
7555
|
+
```javascript
|
|
7556
|
+
import createDiarizationService from 'arcane-os/core/diarization';
|
|
7557
|
+
```
|
|
7558
|
+
|
|
7418
7559
|
## readCoreLaunchContext()
|
|
7419
7560
|
|
|
7420
7561
|
### Overview
|
package/package.json
CHANGED
package/src/core/host.mjs
CHANGED
|
@@ -6,13 +6,22 @@ import {startCoreStdio} from './stdio.mjs';
|
|
|
6
6
|
const is = new Is(false);
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* field meanings belong to the launch owner and individual services.
|
|
9
|
+
* The host's separate state-root argument supplies a launch-context default.
|
|
10
|
+
* Every field in an explicitly selected launch JSON object takes precedence
|
|
11
|
+
* unchanged; field meanings belong to the launch owner and individual services.
|
|
12
12
|
*/
|
|
13
13
|
export async function readCoreLaunchContext({argv = process.argv.slice(2)} = {}) {
|
|
14
|
+
const stateFlag = argv.indexOf('--arcane-host-state-root');
|
|
15
|
+
const defaults = {};
|
|
16
|
+
if (stateFlag !== -1) {
|
|
17
|
+
const stateRoot = argv[stateFlag + 1];
|
|
18
|
+
if (stateRoot === undefined || stateRoot === '') {
|
|
19
|
+
throw new TypeError('--arcane-host-state-root requires a directory.');
|
|
20
|
+
}
|
|
21
|
+
defaults.stateRoot = stateRoot;
|
|
22
|
+
}
|
|
14
23
|
const flag = argv.indexOf('--arcane-launch-config');
|
|
15
|
-
if (flag === -1) return
|
|
24
|
+
if (flag === -1) return defaults;
|
|
16
25
|
const filename = argv[flag + 1];
|
|
17
26
|
if (filename === undefined || filename === '') {
|
|
18
27
|
throw new TypeError('--arcane-launch-config requires a filename.');
|
|
@@ -21,7 +30,7 @@ export async function readCoreLaunchContext({argv = process.argv.slice(2)} = {})
|
|
|
21
30
|
if (context === null || !is.object(context) || is.array(context)) {
|
|
22
31
|
throw new TypeError('Core launch configuration must be a JSON object.');
|
|
23
32
|
}
|
|
24
|
-
return context;
|
|
33
|
+
return {...defaults, ...context};
|
|
25
34
|
}
|
|
26
35
|
|
|
27
36
|
/** Compose app services with the shared dispatcher and draining transport. */
|
|
@@ -69,7 +69,10 @@ namespace Arcane.Core.Hosts.Windows
|
|
|
69
69
|
Title = name,
|
|
70
70
|
ClassicClientSource = File.ReadAllText(Path.Combine(directory, RequiredString(client, "source"))),
|
|
71
71
|
CoreExecutable = Path.Combine(directory, "runtime", "ArcaneCore.exe"),
|
|
72
|
-
|
|
72
|
+
// Forward the actual host selection separately; Core keeps
|
|
73
|
+
// every explicit launch-record field unchanged.
|
|
74
|
+
CoreArguments = "--arcane-host-state-root " + QuoteArgument(profileParent)
|
|
75
|
+
+ (launchFilename == null ? String.Empty : " --arcane-launch-config " + QuoteArgument(launchFilename)),
|
|
73
76
|
// Relative explicit launch filenames retain their caller's
|
|
74
77
|
// meaning; the SEA locates its loader beside its executable.
|
|
75
78
|
CoreWorkingDirectory = Environment.CurrentDirectory
|
package/src/import-map.mjs
CHANGED
|
@@ -2091,8 +2091,8 @@ function scanHtmlStructure(html){
|
|
|
2091
2091
|
return {scripts,links,bases,metas,elements,styles,headClose,bodyClose};
|
|
2092
2092
|
}
|
|
2093
2093
|
|
|
2094
|
-
/**
|
|
2095
|
-
export function removePwaEntryReferences(html, {documentUrl, manifestUrl} = {}) {
|
|
2094
|
+
/** Retire active PWA references; source refresh may restrict removal to marked ownership. */
|
|
2095
|
+
export function removePwaEntryReferences(html, {documentUrl, manifestUrl, markedManifestOnly = false} = {}) {
|
|
2096
2096
|
if (!is.string(html)) throw new TypeError('PWA entry HTML must be a string.');
|
|
2097
2097
|
const structure = scanHtmlStructure(html);
|
|
2098
2098
|
const manifest = new URL(manifestUrl, documentUrl);
|
|
@@ -2106,6 +2106,7 @@ export function removePwaEntryReferences(html, {documentUrl, manifestUrl} = {})
|
|
|
2106
2106
|
const edits = [];
|
|
2107
2107
|
for (const link of structure.links) {
|
|
2108
2108
|
const attributes = parseTagAttributes(link.open);
|
|
2109
|
+
if (markedManifestOnly && !attributes.has('data-arcane-manifest')) continue;
|
|
2109
2110
|
const href = htmlAttributeView(attributes.get('href') ?? '');
|
|
2110
2111
|
const rel = htmlAttributeView(attributes.get('rel') ?? '');
|
|
2111
2112
|
if (!href?.decoded || !rel) continue;
|
|
@@ -2152,7 +2153,7 @@ export function removePwaEntryReferences(html, {documentUrl, manifestUrl} = {})
|
|
|
2152
2153
|
}
|
|
2153
2154
|
|
|
2154
2155
|
/** Update only active PWA entry references; registration never orders application startup. */
|
|
2155
|
-
export function applyPwaEntryReferences(html,{manifestUrl,bootstrapUrl}={}){
|
|
2156
|
+
export function applyPwaEntryReferences(html,{manifestUrl,bootstrapUrl,markGeneratedManifest=false}={}){
|
|
2156
2157
|
if(!is.string(html))throw new TypeError('PWA entry HTML must be a string.');
|
|
2157
2158
|
if(!is.string(manifestUrl)||!manifestUrl||!is.string(bootstrapUrl)||!bootstrapUrl){
|
|
2158
2159
|
throw new TypeError('PWA manifestUrl and bootstrapUrl must be nonempty strings.');
|
|
@@ -2223,7 +2224,10 @@ export function applyPwaEntryReferences(html,{manifestUrl,bootstrapUrl}={}){
|
|
|
2223
2224
|
});
|
|
2224
2225
|
}
|
|
2225
2226
|
}
|
|
2226
|
-
if(!manifestFound)
|
|
2227
|
+
if(!manifestFound){
|
|
2228
|
+
const marker=markGeneratedManifest?' data-arcane-manifest':'';
|
|
2229
|
+
additions.push(`<link rel="manifest" href="${attributeText(manifestUrl)}"${marker}>`);
|
|
2230
|
+
}
|
|
2227
2231
|
let bootstrapFound=false;
|
|
2228
2232
|
for(const script of structure.scripts){
|
|
2229
2233
|
if(!parseTagAttributes(script.open).has('data-arcane-pwa'))continue;
|
package/src/toolchain.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import Is from 'strong-type';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import {resolveAppRoot,resolvePackageOutputRoot} from './app-layout.mjs';
|
|
4
|
-
import {readdir,lstat,realpath,mkdir,readFile,writeFile} from 'node:fs/promises';
|
|
4
|
+
import {readdir,lstat,realpath,mkdir,readFile,writeFile,unlink} from 'node:fs/promises';
|
|
5
5
|
import {createWorkspace,initWorkspace} from './scaffold.mjs';
|
|
6
6
|
import {
|
|
7
7
|
discoverApps as discoverWorkspaceApps,
|
|
@@ -12,8 +12,14 @@ import {
|
|
|
12
12
|
} from './workspace.mjs';
|
|
13
13
|
import {loadArcaneIntegratedProvider} from './integrated-provider-loader.mjs';
|
|
14
14
|
import {collectSourcePwaAssets,startDevServer} from './dev-server.mjs';
|
|
15
|
-
import {applyPwaEntryReferences,generateImportMap,readApplicationTestImportMapContext} from './import-map.mjs';
|
|
16
|
-
import {
|
|
15
|
+
import {applyPwaEntryReferences,generateImportMap,readApplicationTestImportMapContext,removePwaEntryReferences} from './import-map.mjs';
|
|
16
|
+
import {
|
|
17
|
+
createPwaArtifacts,
|
|
18
|
+
PWA_MANIFEST_NAME,
|
|
19
|
+
PWA_OFFLINE_MANIFEST_NAME,
|
|
20
|
+
PWA_WORKER_NAME,
|
|
21
|
+
PWA_BOOTSTRAP_NAME
|
|
22
|
+
} from './pwa.mjs';
|
|
17
23
|
import {readInstalledSdkLayout} from './sdk-runtime-layout.mjs';
|
|
18
24
|
import {withWorkspaceOperationLock} from './workspace-operation-lock.mjs';
|
|
19
25
|
import {refreshAppPackageProjection} from './app-descriptor.mjs';
|
|
@@ -293,7 +299,7 @@ async function validatePreparedRuntime(prepared,{signal}={}){
|
|
|
293
299
|
return validation;
|
|
294
300
|
}
|
|
295
301
|
|
|
296
|
-
async function refreshPreparedImportMap(prepared,{signal,onEvent,workspaceOperationLease}={}){
|
|
302
|
+
async function refreshPreparedImportMap(prepared,{signal,onEvent,workspaceOperationLease}={},retireGeneratedPwa=false){
|
|
297
303
|
const manifest=prepared.validation.app.manifest;
|
|
298
304
|
const inspected=await inspectPackagedApp({
|
|
299
305
|
workspaceRoot:prepared.workspaceRoot,
|
|
@@ -322,12 +328,12 @@ async function refreshPreparedImportMap(prepared,{signal,onEvent,workspaceOperat
|
|
|
322
328
|
onEvent
|
|
323
329
|
});
|
|
324
330
|
if(prepared.validation.config.appsRoot==='.'){
|
|
325
|
-
await refreshRootApplicationFiles(prepared,inspected,importMap,{signal,onEvent});
|
|
331
|
+
await refreshRootApplicationFiles(prepared,inspected,importMap,{signal,onEvent,retireGeneratedPwa});
|
|
326
332
|
}
|
|
327
333
|
return importMap;
|
|
328
334
|
}
|
|
329
335
|
|
|
330
|
-
async function refreshRootApplicationFiles(prepared,inspected,importMap,{signal,onEvent}){
|
|
336
|
+
async function refreshRootApplicationFiles(prepared,inspected,importMap,{signal,onEvent,retireGeneratedPwa=false}){
|
|
331
337
|
const {workspaceRoot,appId}=prepared;
|
|
332
338
|
const manifest=prepared.validation.app.manifest;
|
|
333
339
|
const installed=await readInstalledSdkLayout(workspaceRoot,prepared.validation.config);
|
|
@@ -385,21 +391,44 @@ async function refreshRootApplicationFiles(prepared,inspected,importMap,{signal,
|
|
|
385
391
|
await mkdir(path.dirname(filePath),{recursive:true});
|
|
386
392
|
await writeFile(filePath,file.content,'utf8');
|
|
387
393
|
}
|
|
388
|
-
|
|
394
|
+
const pwaDisabled=manifest.pwa?.enabled===false;
|
|
395
|
+
const retireConfirmedOutput=pwaDisabled&&retireGeneratedPwa===true;
|
|
396
|
+
if(pwa||pwaDisabled){
|
|
389
397
|
for(const document of inspected.browserDocuments){
|
|
390
398
|
throwIfAborted(signal);
|
|
391
399
|
const filePath=path.join(prepared.appRoot,...document.path.split('/'));
|
|
392
400
|
const content=await readFile(filePath,'utf8');
|
|
393
|
-
|
|
401
|
+
const updated=pwa?applyPwaEntryReferences(content,{
|
|
394
402
|
manifestUrl:`/${pwa.entryAssets.manifest}`,
|
|
395
|
-
bootstrapUrl:`/${pwa.entryAssets.bootstrap}
|
|
396
|
-
|
|
403
|
+
bootstrapUrl:`/${pwa.entryAssets.bootstrap}`,
|
|
404
|
+
markGeneratedManifest:true
|
|
405
|
+
}):removePwaEntryReferences(content,{
|
|
406
|
+
documentUrl:new URL(`/${document.path.split('/').map(encodeURIComponent).join('/')}`,sourceOrigin),
|
|
407
|
+
manifestUrl:`/${PWA_MANIFEST_NAME}`,
|
|
408
|
+
markedManifestOnly:!retireConfirmedOutput
|
|
409
|
+
});
|
|
410
|
+
if(updated!==content)await writeFile(filePath,updated,'utf8');
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
const retiredPwa=[];
|
|
414
|
+
if(retireConfirmedOutput){
|
|
415
|
+
// The caller declares these standard outputs generated, not merely same-named authored files.
|
|
416
|
+
// Remove selected references before retiring their targets; browser storage is untouched.
|
|
417
|
+
for(const relative of [PWA_MANIFEST_NAME,PWA_OFFLINE_MANIFEST_NAME,PWA_WORKER_NAME,PWA_BOOTSTRAP_NAME]){
|
|
418
|
+
throwIfAborted(signal);
|
|
419
|
+
try{
|
|
420
|
+
await unlink(path.join(workspaceRoot,relative));
|
|
421
|
+
retiredPwa.push(relative);
|
|
422
|
+
}catch(error){
|
|
423
|
+
if(error.code!=='ENOENT')throw error;
|
|
424
|
+
}
|
|
397
425
|
}
|
|
398
426
|
}
|
|
399
427
|
await emit(onEvent,{
|
|
400
428
|
type:'import-map.root-files.completed',appId,
|
|
401
429
|
navigation:[],
|
|
402
|
-
pwa:pwa?.files.map(file=>file.path)??[]
|
|
430
|
+
pwa:pwa?.files.map(file=>file.path)??[],
|
|
431
|
+
retiredPwa
|
|
403
432
|
});
|
|
404
433
|
}
|
|
405
434
|
|
|
@@ -408,7 +437,7 @@ async function importMapApplication(options={}){
|
|
|
408
437
|
const prepared=await preparedWorkspace({...options,allowMissingManagedImportMap:true});
|
|
409
438
|
const importMap=await ownedWork(
|
|
410
439
|
'import-map',
|
|
411
|
-
context=>refreshPreparedImportMap(prepared,context),
|
|
440
|
+
context=>refreshPreparedImportMap(prepared,context,options.retireGeneratedPwa===true),
|
|
412
441
|
{...options,workspaceRoot:prepared.workspaceRoot}
|
|
413
442
|
);
|
|
414
443
|
await validatePreparedRuntime(prepared,{signal:options.signal});
|