@zhin.js/runtime 1.0.1 → 1.0.3
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/lib/config-composer.js +8 -0
- package/lib/config-patch-planner.js +42 -6
- package/lib/environment-store.js +7 -2
- package/lib/feature-projector.d.ts +4 -4
- package/lib/feature-projector.js +10 -9
- package/lib/generation-assets.d.ts +4 -4
- package/lib/generation-assets.js +29 -7
- package/lib/hmr-coordinator.d.ts +2 -0
- package/lib/hmr-coordinator.js +5 -0
- package/lib/index.d.ts +2 -0
- package/lib/index.js +2 -0
- package/lib/manifest.d.ts +6 -0
- package/lib/manifest.js +9 -1
- package/lib/native-development-runtime.js +26 -2
- package/lib/package-resolver.d.ts +4 -1
- package/lib/package-resolver.js +31 -12
- package/lib/platform-features.d.ts +25 -0
- package/lib/platform-features.js +38 -0
- package/lib/plugin-scope-assembler.d.ts +8 -2
- package/lib/plugin-scope-assembler.js +40 -5
- package/lib/primary-config.d.ts +16 -0
- package/lib/primary-config.js +20 -0
- package/lib/project-graph.d.ts +4 -3
- package/lib/project-graph.js +92 -19
- package/lib/root-runtime.js +97 -40
- package/lib/setup-capabilities.d.ts +5 -0
- package/lib/setup-capabilities.js +44 -0
- package/lib/slot-generation-preparer.js +12 -4
- package/lib/source-ownership.js +2 -0
- package/lib/subtree-generation-preparer.d.ts +3 -1
- package/lib/subtree-generation-preparer.js +13 -6
- package/lib/topology-generation-preparer.d.ts +3 -1
- package/lib/topology-generation-preparer.js +13 -6
- package/package.json +13 -13
|
@@ -24,17 +24,25 @@ export class SlotGenerationPreparer {
|
|
|
24
24
|
for (const slot of replacements)
|
|
25
25
|
capabilities.set(slot.id, slot);
|
|
26
26
|
}
|
|
27
|
-
|
|
27
|
+
// Capability-file HMR projects only the owning Features. The complete
|
|
28
|
+
// snapshot below is assembled by retaining every other projection.
|
|
29
|
+
const providers = [...selectedByFeature.keys()].map((feature) => {
|
|
30
|
+
const provider = this.model.providers.get(feature);
|
|
31
|
+
if (!provider)
|
|
32
|
+
throw new Error(`Missing Feature provider for ${feature}`);
|
|
33
|
+
return provider;
|
|
34
|
+
});
|
|
35
|
+
const projected = await new FeatureProjector(providers).project(current.generation + 1, {
|
|
28
36
|
root: current.root,
|
|
29
37
|
tree: current.tree,
|
|
30
38
|
config: current.config,
|
|
31
39
|
resources: current.resources,
|
|
32
40
|
capabilities,
|
|
33
|
-
});
|
|
41
|
+
}, current.projections);
|
|
34
42
|
try {
|
|
35
43
|
const snapshot = createSnapshotView(current.generation + 1, projected.state);
|
|
36
44
|
const ownership = SourceOwnershipIndex.fromGeneration(this.model.graph, snapshot, this.model.featureIdsByPackageRoot);
|
|
37
|
-
const assets = this.model.assets.
|
|
45
|
+
const assets = this.model.assets.replaceProjections(selectedByFeature.keys(), projected.disposers);
|
|
38
46
|
return {
|
|
39
47
|
generation: {
|
|
40
48
|
snapshot: projected.state,
|
|
@@ -46,7 +54,7 @@ export class SlotGenerationPreparer {
|
|
|
46
54
|
};
|
|
47
55
|
}
|
|
48
56
|
catch (error) {
|
|
49
|
-
await disposeProjections(projected.disposers, error);
|
|
57
|
+
await disposeProjections(projected.disposers.values(), error);
|
|
50
58
|
throw error;
|
|
51
59
|
}
|
|
52
60
|
}
|
package/lib/source-ownership.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type PluginId, type RuntimeSnapshot } from '@zhin.js/plugin-runtime';
|
|
2
2
|
import type { RuntimeEnvironment } from './environment.js';
|
|
3
3
|
import type { EnvironmentLayers } from './environment-store.js';
|
|
4
|
+
import type { RuntimeConfigDocument } from './config-composer.js';
|
|
4
5
|
import type { IsolatedPluginRuntimePort } from './isolation.js';
|
|
5
6
|
import type { ModuleRuntime } from './module-runtime.js';
|
|
6
7
|
import { type PluginConfigResolver, type RootResourceInstaller } from './plugin-scope-assembler.js';
|
|
@@ -15,10 +16,11 @@ export declare class SubtreeGenerationPreparer {
|
|
|
15
16
|
private readonly model;
|
|
16
17
|
private readonly graph;
|
|
17
18
|
private readonly configResolver;
|
|
19
|
+
private readonly primaryConfigDocument;
|
|
18
20
|
private readonly environment;
|
|
19
21
|
private readonly installResources?;
|
|
20
22
|
private readonly environmentLayers;
|
|
21
23
|
private readonly isolation?;
|
|
22
|
-
constructor(modules: ModuleRuntime, model: RuntimeGenerationModel, graph: ProjectGraph, configResolver: PluginConfigResolver, environment: RuntimeEnvironment, installResources?: RootResourceInstaller | undefined, environmentLayers?: EnvironmentLayers, isolation?: IsolatedPluginRuntimePort | undefined);
|
|
24
|
+
constructor(modules: ModuleRuntime, model: RuntimeGenerationModel, graph: ProjectGraph, configResolver: PluginConfigResolver, primaryConfigDocument: RuntimeConfigDocument, environment: RuntimeEnvironment, installResources?: RootResourceInstaller | undefined, environmentLayers?: EnvironmentLayers, isolation?: IsolatedPluginRuntimePort | undefined);
|
|
23
25
|
prepare(current: RuntimeSnapshot, roots: readonly PluginId[]): Promise<PreparedRuntimeGeneration>;
|
|
24
26
|
}
|
|
@@ -4,6 +4,7 @@ import { FeatureProjector, composeGenerationHandoffs } from './feature-projector
|
|
|
4
4
|
import { NodeDiscoveryHost } from './node-discovery-host.js';
|
|
5
5
|
import { PluginScopeAssembler, } from './plugin-scope-assembler.js';
|
|
6
6
|
import { SourceOwnershipIndex } from './source-ownership.js';
|
|
7
|
+
import { addCapabilitySlot, featureSetupAliases, mergeSetupCapabilities, } from './setup-capabilities.js';
|
|
7
8
|
export class SubtreeTopologyChangedError extends Error {
|
|
8
9
|
constructor(message) {
|
|
9
10
|
super(message);
|
|
@@ -16,15 +17,17 @@ export class SubtreeGenerationPreparer {
|
|
|
16
17
|
model;
|
|
17
18
|
graph;
|
|
18
19
|
configResolver;
|
|
20
|
+
primaryConfigDocument;
|
|
19
21
|
environment;
|
|
20
22
|
installResources;
|
|
21
23
|
environmentLayers;
|
|
22
24
|
isolation;
|
|
23
|
-
constructor(modules, model, graph, configResolver, environment, installResources, environmentLayers = {}, isolation) {
|
|
25
|
+
constructor(modules, model, graph, configResolver, primaryConfigDocument, environment, installResources, environmentLayers = {}, isolation) {
|
|
24
26
|
this.modules = modules;
|
|
25
27
|
this.model = model;
|
|
26
28
|
this.graph = graph;
|
|
27
29
|
this.configResolver = configResolver;
|
|
30
|
+
this.primaryConfigDocument = primaryConfigDocument;
|
|
28
31
|
this.environment = environment;
|
|
29
32
|
this.installResources = installResources;
|
|
30
33
|
this.environmentLayers = environmentLayers;
|
|
@@ -33,14 +36,15 @@ export class SubtreeGenerationPreparer {
|
|
|
33
36
|
async prepare(current, roots) {
|
|
34
37
|
const nodes = indexGraph(this.graph);
|
|
35
38
|
assertCompatibleTopology(indexGraph(this.model.graph), nodes, roots);
|
|
36
|
-
const plugins = new PluginScopeAssembler(this.modules, this.configResolver, this.environment, this.installResources, this.environmentLayers, {
|
|
39
|
+
const plugins = new PluginScopeAssembler(this.modules, this.configResolver, this.environment, this.primaryConfigDocument, this.installResources, this.environmentLayers, {
|
|
37
40
|
scopes: this.model.scopes,
|
|
38
41
|
tree: current.tree,
|
|
39
42
|
config: current.config,
|
|
40
43
|
resources: current.resources,
|
|
41
44
|
}, this.isolation);
|
|
45
|
+
plugins.installSetupFeatureAliases(featureSetupAliases(this.model.providers.values()));
|
|
42
46
|
plugins.removeSubtrees(roots);
|
|
43
|
-
const projectionDisposers =
|
|
47
|
+
const projectionDisposers = new Map();
|
|
44
48
|
try {
|
|
45
49
|
for (const root of roots) {
|
|
46
50
|
const node = nodes.get(root);
|
|
@@ -53,6 +57,7 @@ export class SubtreeGenerationPreparer {
|
|
|
53
57
|
if (roots.some((root) => isWithin(slot.owner, root)))
|
|
54
58
|
capabilities.delete(id);
|
|
55
59
|
}
|
|
60
|
+
mergeSetupCapabilities(capabilities, plugins.setupCapabilities(), this.model.providers, this.model.rootsByFeature);
|
|
56
61
|
const discovery = new FeatureDiscovery(new NodeDiscoveryHost(this.modules));
|
|
57
62
|
for (const provider of this.model.providers.values()) {
|
|
58
63
|
const affectedRoots = (this.model.rootsByFeature.get(provider.id) ?? [])
|
|
@@ -61,7 +66,7 @@ export class SubtreeGenerationPreparer {
|
|
|
61
66
|
continue;
|
|
62
67
|
const slots = await discovery.discover(provider, affectedRoots);
|
|
63
68
|
for (const slot of slots)
|
|
64
|
-
capabilities
|
|
69
|
+
addCapabilitySlot(capabilities, slot);
|
|
65
70
|
}
|
|
66
71
|
const projected = await new FeatureProjector(this.model.providers.values()).project(current.generation + 1, {
|
|
67
72
|
root: current.root,
|
|
@@ -70,7 +75,9 @@ export class SubtreeGenerationPreparer {
|
|
|
70
75
|
resources: plugins.resources,
|
|
71
76
|
capabilities,
|
|
72
77
|
});
|
|
73
|
-
|
|
78
|
+
for (const [feature, dispose] of projected.disposers) {
|
|
79
|
+
projectionDisposers.set(feature, dispose);
|
|
80
|
+
}
|
|
74
81
|
const snapshot = createSnapshotView(current.generation + 1, projected.state);
|
|
75
82
|
const ownership = SourceOwnershipIndex.fromGeneration(this.graph, snapshot, this.model.featureIdsByPackageRoot);
|
|
76
83
|
const replacements = new Map(plugins.createdScopeDisposers());
|
|
@@ -93,7 +100,7 @@ export class SubtreeGenerationPreparer {
|
|
|
93
100
|
};
|
|
94
101
|
}
|
|
95
102
|
catch (error) {
|
|
96
|
-
await rollback(plugins.createdScopeDisposers().map(([, dispose]) => dispose), projectionDisposers, error);
|
|
103
|
+
await rollback(plugins.createdScopeDisposers().map(([, dispose]) => dispose), [...projectionDisposers.values()], error);
|
|
97
104
|
throw error;
|
|
98
105
|
}
|
|
99
106
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type RuntimeSnapshot } from '@zhin.js/plugin-runtime';
|
|
2
2
|
import type { RuntimeEnvironment } from './environment.js';
|
|
3
3
|
import type { EnvironmentLayers } from './environment-store.js';
|
|
4
|
+
import type { RuntimeConfigDocument } from './config-composer.js';
|
|
4
5
|
import type { IsolatedPluginRuntimePort } from './isolation.js';
|
|
5
6
|
import type { ModuleRuntime } from './module-runtime.js';
|
|
6
7
|
import { type PluginConfigResolver, type RootResourceInstaller } from './plugin-scope-assembler.js';
|
|
@@ -13,10 +14,11 @@ export declare class TopologyGenerationPreparer {
|
|
|
13
14
|
private readonly model;
|
|
14
15
|
private readonly graph;
|
|
15
16
|
private readonly configResolver;
|
|
17
|
+
private readonly primaryConfigDocument;
|
|
16
18
|
private readonly environment;
|
|
17
19
|
private readonly installResources?;
|
|
18
20
|
private readonly environmentLayers;
|
|
19
21
|
private readonly isolation?;
|
|
20
|
-
constructor(modules: ModuleRuntime, model: RuntimeGenerationModel, graph: ProjectGraph, configResolver: PluginConfigResolver, environment: RuntimeEnvironment, installResources?: RootResourceInstaller | undefined, environmentLayers?: EnvironmentLayers, isolation?: IsolatedPluginRuntimePort | undefined);
|
|
22
|
+
constructor(modules: ModuleRuntime, model: RuntimeGenerationModel, graph: ProjectGraph, configResolver: PluginConfigResolver, primaryConfigDocument: RuntimeConfigDocument, environment: RuntimeEnvironment, installResources?: RootResourceInstaller | undefined, environmentLayers?: EnvironmentLayers, isolation?: IsolatedPluginRuntimePort | undefined);
|
|
21
23
|
prepare(current: RuntimeSnapshot): Promise<PreparedRuntimeGeneration | undefined>;
|
|
22
24
|
}
|
|
@@ -6,6 +6,7 @@ import { FeatureProjector, composeGenerationHandoffs } from './feature-projector
|
|
|
6
6
|
import { NodeDiscoveryHost } from './node-discovery-host.js';
|
|
7
7
|
import { PluginScopeAssembler, } from './plugin-scope-assembler.js';
|
|
8
8
|
import { SourceOwnershipIndex } from './source-ownership.js';
|
|
9
|
+
import { addCapabilitySlot, featureSetupAliases, mergeSetupCapabilities, } from './setup-capabilities.js';
|
|
9
10
|
import { TopologyTransactionPlanner, collapseRoots, graphNodes, graphOrder, isWithin, } from './topology-transaction.js';
|
|
10
11
|
/** Prepares manifest topology changes without rebuilding stable Plugin Scopes. */
|
|
11
12
|
export class TopologyGenerationPreparer {
|
|
@@ -13,15 +14,17 @@ export class TopologyGenerationPreparer {
|
|
|
13
14
|
model;
|
|
14
15
|
graph;
|
|
15
16
|
configResolver;
|
|
17
|
+
primaryConfigDocument;
|
|
16
18
|
environment;
|
|
17
19
|
installResources;
|
|
18
20
|
environmentLayers;
|
|
19
21
|
isolation;
|
|
20
|
-
constructor(modules, model, graph, configResolver, environment, installResources, environmentLayers = {}, isolation) {
|
|
22
|
+
constructor(modules, model, graph, configResolver, primaryConfigDocument, environment, installResources, environmentLayers = {}, isolation) {
|
|
21
23
|
this.modules = modules;
|
|
22
24
|
this.model = model;
|
|
23
25
|
this.graph = graph;
|
|
24
26
|
this.configResolver = configResolver;
|
|
27
|
+
this.primaryConfigDocument = primaryConfigDocument;
|
|
25
28
|
this.environment = environment;
|
|
26
29
|
this.installResources = installResources;
|
|
27
30
|
this.environmentLayers = environmentLayers;
|
|
@@ -39,12 +42,13 @@ export class TopologyGenerationPreparer {
|
|
|
39
42
|
if (!plan.changed)
|
|
40
43
|
return undefined;
|
|
41
44
|
const featureTopology = await this.#loadFeatureTopology(plan);
|
|
42
|
-
const plugins = new PluginScopeAssembler(this.modules, this.configResolver, this.environment, this.installResources, this.environmentLayers, {
|
|
45
|
+
const plugins = new PluginScopeAssembler(this.modules, this.configResolver, this.environment, this.primaryConfigDocument, this.installResources, this.environmentLayers, {
|
|
43
46
|
scopes: this.model.scopes,
|
|
44
47
|
tree: current.tree,
|
|
45
48
|
config: current.config,
|
|
46
49
|
resources: current.resources,
|
|
47
50
|
}, this.isolation);
|
|
51
|
+
plugins.installSetupFeatureAliases(featureSetupAliases(featureTopology.providers.values()));
|
|
48
52
|
const setupRoots = collapseRoots([
|
|
49
53
|
...plan.addedPluginRoots,
|
|
50
54
|
...plan.replacedPluginRoots,
|
|
@@ -54,7 +58,7 @@ export class TopologyGenerationPreparer {
|
|
|
54
58
|
...plan.replacedPluginRoots,
|
|
55
59
|
]);
|
|
56
60
|
plugins.removeSubtrees(removalRoots);
|
|
57
|
-
const projectionDisposers =
|
|
61
|
+
const projectionDisposers = new Map();
|
|
58
62
|
try {
|
|
59
63
|
for (const root of setupRoots) {
|
|
60
64
|
const node = nextNodes.get(root);
|
|
@@ -66,6 +70,7 @@ export class TopologyGenerationPreparer {
|
|
|
66
70
|
// remove, move, or reorder operations.
|
|
67
71
|
plugins.synchronizeTree(this.graph.root);
|
|
68
72
|
const capabilities = await this.#prepareCapabilities(current, plan, setupRoots, featureTopology);
|
|
73
|
+
mergeSetupCapabilities(capabilities, plugins.setupCapabilities(), featureTopology.providers, featureTopology.rootsByFeature);
|
|
69
74
|
const projected = await new FeatureProjector(featureTopology.providers.values()).project(current.generation + 1, {
|
|
70
75
|
root: current.root,
|
|
71
76
|
tree: plugins.tree,
|
|
@@ -73,7 +78,9 @@ export class TopologyGenerationPreparer {
|
|
|
73
78
|
resources: plugins.resources,
|
|
74
79
|
capabilities,
|
|
75
80
|
});
|
|
76
|
-
|
|
81
|
+
for (const [feature, dispose] of projected.disposers) {
|
|
82
|
+
projectionDisposers.set(feature, dispose);
|
|
83
|
+
}
|
|
77
84
|
const snapshot = createSnapshotView(current.generation + 1, projected.state);
|
|
78
85
|
const ownership = SourceOwnershipIndex.fromGeneration(this.graph, snapshot, featureTopology.featureIdsByPackageRoot);
|
|
79
86
|
const replacements = new Map(plugins.createdScopeDisposers());
|
|
@@ -96,7 +103,7 @@ export class TopologyGenerationPreparer {
|
|
|
96
103
|
};
|
|
97
104
|
}
|
|
98
105
|
catch (error) {
|
|
99
|
-
await rollback(plugins.createdScopeDisposers().map(([, dispose]) => dispose), projectionDisposers, error);
|
|
106
|
+
await rollback(plugins.createdScopeDisposers().map(([, dispose]) => dispose), [...projectionDisposers.values()], error);
|
|
100
107
|
throw error;
|
|
101
108
|
}
|
|
102
109
|
}
|
|
@@ -175,7 +182,7 @@ export class TopologyGenerationPreparer {
|
|
|
175
182
|
if (!provider)
|
|
176
183
|
throw new Error(`Missing Feature provider for ${feature}`);
|
|
177
184
|
for (const slot of await discovery.discover(provider, selected)) {
|
|
178
|
-
capabilities
|
|
185
|
+
addCapabilitySlot(capabilities, slot);
|
|
179
186
|
}
|
|
180
187
|
}
|
|
181
188
|
return capabilities;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zhin.js/runtime",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"description": "Static Plugin graph, generation transaction and HMR Root runtime for Zhin.js",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./lib/index.js",
|
|
@@ -18,22 +18,22 @@
|
|
|
18
18
|
"dependencies": {
|
|
19
19
|
"ajv": "8.18.0",
|
|
20
20
|
"semver": "7.8.5",
|
|
21
|
-
"@zhin.js/feature-kit": "1.0.
|
|
22
|
-
"@zhin.js/plugin-runtime": "1.
|
|
21
|
+
"@zhin.js/feature-kit": "1.0.3",
|
|
22
|
+
"@zhin.js/plugin-runtime": "1.1.1"
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
25
25
|
"@types/node": "^26.1.0",
|
|
26
26
|
"typescript": "^6.0.3",
|
|
27
|
-
"@zhin.js/adapter": "1.
|
|
28
|
-
"@zhin.js/agent-feature": "1.0.
|
|
29
|
-
"@zhin.js/command": "1.0.
|
|
30
|
-
"@zhin.js/
|
|
31
|
-
"@zhin.js/
|
|
32
|
-
"@zhin.js/
|
|
33
|
-
"@zhin.js/
|
|
34
|
-
"@zhin.js/page": "1.0.
|
|
35
|
-
"@zhin.js/skill": "1.0.
|
|
36
|
-
"@zhin.js/tool": "1.0.
|
|
27
|
+
"@zhin.js/adapter": "1.1.1",
|
|
28
|
+
"@zhin.js/agent-feature": "1.0.3",
|
|
29
|
+
"@zhin.js/command": "1.0.3",
|
|
30
|
+
"@zhin.js/component": "1.0.3",
|
|
31
|
+
"@zhin.js/layout": "1.0.3",
|
|
32
|
+
"@zhin.js/mcp-feature": "1.0.3",
|
|
33
|
+
"@zhin.js/middleware": "1.0.3",
|
|
34
|
+
"@zhin.js/page": "1.0.3",
|
|
35
|
+
"@zhin.js/skill": "1.0.3",
|
|
36
|
+
"@zhin.js/tool": "1.0.3"
|
|
37
37
|
},
|
|
38
38
|
"repository": {
|
|
39
39
|
"type": "git",
|