@appshell/react 1.0.0-alpha.0 → 1.0.0-alpha.100
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/README.md +36 -49
- package/dist/main.js +1 -1
- package/dist/types/config/src/axios.d.ts +0 -1
- package/dist/types/config/src/configmap.d.ts +0 -1
- package/dist/types/config/src/context.d.ts +26 -0
- package/dist/types/config/src/credentials.d.ts +48 -0
- package/dist/types/config/src/generate.manifest.d.ts +30 -2
- package/dist/types/config/src/index.d.ts +12 -9
- package/dist/types/config/src/loader.d.ts +18 -0
- package/dist/types/config/src/mappers/appshell.config.d.ts +9 -3
- package/dist/types/config/src/outdated.d.ts +0 -1
- package/dist/types/config/src/package-name.d.ts +20 -0
- package/dist/types/config/src/publish.d.ts +93 -8
- package/dist/types/config/src/sync.d.ts +0 -1
- package/dist/types/config/src/tls.d.ts +11 -0
- package/dist/types/config/src/types.d.ts +184 -31
- package/dist/types/config/src/utils/blur.d.ts +0 -1
- package/dist/types/config/src/utils/compare.d.ts +0 -1
- package/dist/types/config/src/utils/config.d.ts +15 -1
- package/dist/types/config/src/utils/copy.d.ts +0 -1
- package/dist/types/config/src/utils/dump.d.ts +10 -0
- package/dist/types/config/src/utils/index.d.ts +2 -5
- package/dist/types/config/src/utils/list.d.ts +0 -1
- package/dist/types/config/src/utils/load.d.ts +0 -1
- package/dist/types/config/src/validators/AppshellTemplateValidator.d.ts +0 -1
- package/dist/types/config/src/validators/index.d.ts +0 -3
- package/dist/types/loader/src/index.d.ts +0 -1
- package/dist/types/loader/src/loadAppshellComponent.d.ts +13 -14
- package/dist/types/loader/src/remoteLoader.d.ts +2 -3
- package/dist/types/loader/src/resolvers.d.ts +4 -12
- package/dist/types/loader/src/types.d.ts +0 -1
- package/dist/types/react/src/components/LoadingError.d.ts +0 -1
- package/dist/types/react/src/components/RemoteSlot.d.ts +28 -0
- package/dist/types/react/src/contexts/RemoteContext.d.ts +2 -4
- package/dist/types/react/src/hooks/useRemote.d.ts +1 -2
- package/dist/types/react/src/index.d.ts +2 -9
- package/dist/types/react/src/resources/jsonResource.d.ts +0 -1
- package/dist/types/react/src/types.d.ts +0 -1
- package/dist/types/runtime/src/errors.d.ts +32 -0
- package/dist/types/runtime/src/identity.d.ts +47 -0
- package/dist/types/runtime/src/index.d.ts +6 -0
- package/dist/types/runtime/src/store.d.ts +25 -0
- package/dist/types/runtime/src/types.d.ts +9 -0
- package/dist/types/runtime/src/wire.d.ts +58 -0
- package/package.json +14 -4
- package/CHANGELOG.md +0 -191
- package/__tests__/AppshellComponent.spec.tsx +0 -53
- package/__tests__/LoadingError.spec.tsx +0 -14
- package/__tests__/ManifestContext.spec.tsx +0 -50
- package/__tests__/ReactHost.spec.tsx +0 -136
- package/__tests__/__snapshots__/AppshellComponent.spec.tsx.snap +0 -9
- package/__tests__/__snapshots__/LoadingError.spec.tsx.snap +0 -88
- package/__tests__/__snapshots__/ReactHost.spec.tsx.snap +0 -11
- package/__tests__/fixtures/Manifest.ts +0 -16
- package/__tests__/fixtures/TestComponent.tsx +0 -5
- package/__tests__/fixtures/TestGlobalConfig.ts +0 -8
- package/__tests__/jsonResource.spec.ts +0 -27
- package/__tests__/useRemote.spec.tsx +0 -36
- package/__tests__/utils/waitForResource.ts +0 -15
- package/dist/types/config/src/axios.d.ts.map +0 -1
- package/dist/types/config/src/configmap.d.ts.map +0 -1
- package/dist/types/config/src/deregister.d.ts +0 -3
- package/dist/types/config/src/deregister.d.ts.map +0 -1
- package/dist/types/config/src/generate.env.d.ts +0 -3
- package/dist/types/config/src/generate.env.d.ts.map +0 -1
- package/dist/types/config/src/generate.global-config.d.ts +0 -10
- package/dist/types/config/src/generate.global-config.d.ts.map +0 -1
- package/dist/types/config/src/generate.manifest.d.ts.map +0 -1
- package/dist/types/config/src/index.d.ts.map +0 -1
- package/dist/types/config/src/mappers/appshell.config.d.ts.map +0 -1
- package/dist/types/config/src/outdated.d.ts.map +0 -1
- package/dist/types/config/src/publish.d.ts.map +0 -1
- package/dist/types/config/src/register.d.ts +0 -4
- package/dist/types/config/src/register.d.ts.map +0 -1
- package/dist/types/config/src/sync.d.ts.map +0 -1
- package/dist/types/config/src/types.d.ts.map +0 -1
- package/dist/types/config/src/utils/blur.d.ts.map +0 -1
- package/dist/types/config/src/utils/compare.d.ts.map +0 -1
- package/dist/types/config/src/utils/config.d.ts.map +0 -1
- package/dist/types/config/src/utils/copy.d.ts.map +0 -1
- package/dist/types/config/src/utils/index.d.ts.map +0 -1
- package/dist/types/config/src/utils/isValidUrl.d.ts +0 -3
- package/dist/types/config/src/utils/isValidUrl.d.ts.map +0 -1
- package/dist/types/config/src/utils/list.d.ts.map +0 -1
- package/dist/types/config/src/utils/load.d.ts.map +0 -1
- package/dist/types/config/src/utils/loadJson.d.ts +0 -10
- package/dist/types/config/src/utils/loadJson.d.ts.map +0 -1
- package/dist/types/config/src/utils/merge.d.ts +0 -4
- package/dist/types/config/src/utils/merge.d.ts.map +0 -1
- package/dist/types/config/src/validators/AppshellGlobalConfigValidator.d.ts +0 -4
- package/dist/types/config/src/validators/AppshellGlobalConfigValidator.d.ts.map +0 -1
- package/dist/types/config/src/validators/AppshellManifestValidator.d.ts +0 -4
- package/dist/types/config/src/validators/AppshellManifestValidator.d.ts.map +0 -1
- package/dist/types/config/src/validators/AppshellTemplateValidator.d.ts.map +0 -1
- package/dist/types/config/src/validators/index.d.ts.map +0 -1
- package/dist/types/loader/src/fetchDynamicScript.d.ts +0 -3
- package/dist/types/loader/src/fetchDynamicScript.d.ts.map +0 -1
- package/dist/types/loader/src/index.d.ts.map +0 -1
- package/dist/types/loader/src/loadAppshellComponent.d.ts.map +0 -1
- package/dist/types/loader/src/remoteLoader.d.ts.map +0 -1
- package/dist/types/loader/src/resolvers.d.ts.map +0 -1
- package/dist/types/loader/src/types.d.ts.map +0 -1
- package/dist/types/react/src/components/AppshellComponent.d.ts +0 -30
- package/dist/types/react/src/components/AppshellComponent.d.ts.map +0 -1
- package/dist/types/react/src/components/LoadingError.d.ts.map +0 -1
- package/dist/types/react/src/components/ReactHost.d.ts +0 -9
- package/dist/types/react/src/components/ReactHost.d.ts.map +0 -1
- package/dist/types/react/src/contexts/GlobalConfigContext.d.ts +0 -11
- package/dist/types/react/src/contexts/GlobalConfigContext.d.ts.map +0 -1
- package/dist/types/react/src/contexts/ManifestContext.d.ts +0 -12
- package/dist/types/react/src/contexts/ManifestContext.d.ts.map +0 -1
- package/dist/types/react/src/contexts/MetadataContext.d.ts +0 -11
- package/dist/types/react/src/contexts/MetadataContext.d.ts.map +0 -1
- package/dist/types/react/src/contexts/RemoteContext.d.ts.map +0 -1
- package/dist/types/react/src/hooks/useGlobalConfig.d.ts +0 -4
- package/dist/types/react/src/hooks/useGlobalConfig.d.ts.map +0 -1
- package/dist/types/react/src/hooks/useManifest.d.ts +0 -4
- package/dist/types/react/src/hooks/useManifest.d.ts.map +0 -1
- package/dist/types/react/src/hooks/useMetadata.d.ts +0 -4
- package/dist/types/react/src/hooks/useMetadata.d.ts.map +0 -1
- package/dist/types/react/src/hooks/useRemote.d.ts.map +0 -1
- package/dist/types/react/src/index.d.ts.map +0 -1
- package/dist/types/react/src/resources/jsonResource.d.ts.map +0 -1
- package/dist/types/react/src/types.d.ts.map +0 -1
- package/src/components/AppshellComponent.tsx +0 -82
- package/src/components/LoadingError.tsx +0 -15
- package/src/components/ReactHost.tsx +0 -55
- package/src/contexts/GlobalConfigContext.tsx +0 -17
- package/src/contexts/ManifestContext.tsx +0 -40
- package/src/contexts/MetadataContext.tsx +0 -17
- package/src/contexts/RemoteContext.tsx +0 -22
- package/src/hooks/useGlobalConfig.ts +0 -7
- package/src/hooks/useManifest.ts +0 -7
- package/src/hooks/useMetadata.ts +0 -6
- package/src/hooks/useRemote.ts +0 -7
- package/src/index.ts +0 -11
- package/src/resources/jsonResource.ts +0 -35
- package/src/types.ts +0 -3
- package/tsconfig.json +0 -7
- package/webpack.config.js +0 -42
|
@@ -1,26 +1,111 @@
|
|
|
1
|
-
import { AppshellManifest, Metadata } from './types';
|
|
1
|
+
import { AppshellManifest, Metadata, ModuleFederationLoader } from './types';
|
|
2
2
|
export type PublishOptions = {
|
|
3
3
|
registry: string;
|
|
4
4
|
token?: string;
|
|
5
|
+
/**
|
|
6
|
+
* Where this package belongs, when the package name declares it.
|
|
7
|
+
*
|
|
8
|
+
* Omitted means the publisher's own namespace, which is how every publish worked before
|
|
9
|
+
* this existed. The registry refuses a scope the caller does not own, so declaring one
|
|
10
|
+
* is a statement of fact rather than a request.
|
|
11
|
+
*/
|
|
12
|
+
scopeId?: string;
|
|
5
13
|
name: string;
|
|
6
14
|
version: string;
|
|
7
15
|
manifest: AppshellManifest;
|
|
8
16
|
visibility?: 'public' | 'private';
|
|
9
17
|
metadata?: Metadata;
|
|
18
|
+
/** Ask the registry to overwrite an existing version whose content differs. */
|
|
19
|
+
force?: boolean;
|
|
10
20
|
};
|
|
11
21
|
export type PublishResult = {
|
|
12
|
-
/** `scope/name@version`.
|
|
22
|
+
/** `scope/name@version`. From the package name where it declares one, else the token. */
|
|
13
23
|
id: string;
|
|
14
24
|
created: boolean;
|
|
25
|
+
/** Empty unless a shared block was sent. See `openOverlay`. */
|
|
26
|
+
divergence: SharedDivergence[];
|
|
15
27
|
};
|
|
16
28
|
/**
|
|
17
29
|
* Publishing the same content twice is a no-op; publishing different content
|
|
18
|
-
* under a version that already exists is rejected by the registry
|
|
30
|
+
* under a version that already exists is rejected by the registry, unless
|
|
31
|
+
* `force` is set and the registry is configured to honor it (dev registries).
|
|
19
32
|
*/
|
|
20
|
-
export declare const publish: ({ registry, token, name, version, manifest, visibility, metadata, }: PublishOptions) => Promise<PublishResult>;
|
|
33
|
+
export declare const publish: ({ registry, token, scopeId, name, version, manifest, visibility, metadata, force, }: PublishOptions) => Promise<PublishResult>;
|
|
21
34
|
/**
|
|
22
|
-
* Activating a newer version of an already active
|
|
23
|
-
* @param
|
|
35
|
+
* Activating a newer version of an already active package upgrades it in place.
|
|
36
|
+
* @param application `scope/name`
|
|
24
37
|
*/
|
|
25
|
-
export declare const activate: (registry: string,
|
|
26
|
-
|
|
38
|
+
export declare const activate: (registry: string, application: string, packageId: string, token?: string) => Promise<void>;
|
|
39
|
+
/** What an overlay redirects a single remote to, or introduces one as. */
|
|
40
|
+
export type OverlayRemotePatch = {
|
|
41
|
+
remoteEntryUrl: string;
|
|
42
|
+
manifestUrl?: string;
|
|
43
|
+
/**
|
|
44
|
+
* How to load this build's copy, from the Module Federation config that emits it.
|
|
45
|
+
*
|
|
46
|
+
* Sent because the loader describes the code being loaded, and an overlay points at
|
|
47
|
+
* this build rather than the published one. Without it a redirect addresses a dev
|
|
48
|
+
* server's bundle by whatever container name the last publish happened to have, so
|
|
49
|
+
* renaming the container locally resolves to a container the browser cannot find.
|
|
50
|
+
*
|
|
51
|
+
* It is also what lets an overlay introduce a component that is not published yet: a
|
|
52
|
+
* redirect inherits the published loader, an addition has no published anything.
|
|
53
|
+
*/
|
|
54
|
+
loader?: ModuleFederationLoader;
|
|
55
|
+
/**
|
|
56
|
+
* The remote's `metadata` as this build declares it.
|
|
57
|
+
*
|
|
58
|
+
* Sent because a developer iterating on `appshell.config.yaml` is editing metadata as
|
|
59
|
+
* much as code; without it an overlay serves their new bundle beside the published
|
|
60
|
+
* route, displayName and icon. The registry replaces rather than merges, so a key
|
|
61
|
+
* removed from the yaml disappears rather than standing.
|
|
62
|
+
*/
|
|
63
|
+
metadata?: Metadata;
|
|
64
|
+
};
|
|
65
|
+
/** One shared dependency where a local build and the published version disagree. */
|
|
66
|
+
export type SharedDivergence = {
|
|
67
|
+
packageId: string;
|
|
68
|
+
shareScope: string;
|
|
69
|
+
packageName: string;
|
|
70
|
+
published?: string;
|
|
71
|
+
local?: string;
|
|
72
|
+
singleton: {
|
|
73
|
+
published: boolean;
|
|
74
|
+
local: boolean;
|
|
75
|
+
};
|
|
76
|
+
};
|
|
77
|
+
export type OpenedOverlay = {
|
|
78
|
+
id: string;
|
|
79
|
+
confirmUrl: string;
|
|
80
|
+
url: string;
|
|
81
|
+
remotes: string[];
|
|
82
|
+
expiresAt: string;
|
|
83
|
+
/**
|
|
84
|
+
* False when an overlay was already open for this developer and this one extended it.
|
|
85
|
+
* A browser carries a single overlay id, so an extended overlay is one some browser has
|
|
86
|
+
* already confirmed — nothing needs sending back to the confirmation page.
|
|
87
|
+
*/
|
|
88
|
+
created: boolean;
|
|
89
|
+
/**
|
|
90
|
+
* What this build declares that the published version does not. Empty unless a shared
|
|
91
|
+
* block was sent — see `openOverlay`.
|
|
92
|
+
*/
|
|
93
|
+
divergence: SharedDivergence[];
|
|
94
|
+
};
|
|
95
|
+
/**
|
|
96
|
+
* Points some of an application's remotes at a developer's own machine, for that
|
|
97
|
+
* developer only.
|
|
98
|
+
*
|
|
99
|
+
* This is what a local dev loop does instead of republishing. A published version is
|
|
100
|
+
* immutable and content-addressed; overwriting one on every rebuild makes the digest
|
|
101
|
+
* describe whoever built last, and two developers sharing a registry overwrite each
|
|
102
|
+
* other. An overlay is per-developer, per-browser and expiring, so neither happens.
|
|
103
|
+
*
|
|
104
|
+
* Extending is the normal case rather than the exception: the registry merges remotes
|
|
105
|
+
* into whatever overlay this developer already holds, so serving two micro-frontends
|
|
106
|
+
* locally redirects both without minting a second overlay or asking for confirmation
|
|
107
|
+
* twice.
|
|
108
|
+
*
|
|
109
|
+
* @param application `scope/name`
|
|
110
|
+
*/
|
|
111
|
+
export declare const openOverlay: (registry: string, application: string, remotes: Record<string, OverlayRemotePatch>, token?: string, shared?: Record<string, unknown>, shellFlavor?: "prod" | "dev") => Promise<OpenedOverlay>;
|
|
@@ -18,4 +18,3 @@ export declare const groupByBaselineModule: (conflicts: Record<string, Compariso
|
|
|
18
18
|
*/
|
|
19
19
|
declare const _default: (workingDir: string, registry: string, conflicts: Record<string, ComparisonResult>, resolutionStrategy?: ResolutionStrategy, packageManager?: PackageManager, dryRun?: boolean) => Promise<void>;
|
|
20
20
|
export default _default;
|
|
21
|
-
//# sourceMappingURL=sync.d.ts.map
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import https from 'https';
|
|
2
|
+
export declare const caFile: () => string | undefined;
|
|
3
|
+
/**
|
|
4
|
+
* The agent to use for registry and issuer requests, or undefined when no CA is
|
|
5
|
+
* configured and Node's defaults apply.
|
|
6
|
+
*
|
|
7
|
+
* A configured file that does not exist throws rather than being skipped: falling back
|
|
8
|
+
* silently would reproduce the original certificate error, having been told exactly how
|
|
9
|
+
* to avoid it.
|
|
10
|
+
*/
|
|
11
|
+
export declare const httpsAgent: () => https.Agent | undefined;
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import type { AppshellIndex, AppshellRemote, Metadata, RemoteLoader } from '@appshell/runtime';
|
|
1
2
|
import { JSONSchema4, JSONSchema6, JSONSchema7 } from 'json-schema';
|
|
3
|
+
export type { AppshellIndex, AppshellRemote, Metadata, ModuleFederationLoader, RemoteLoader, } from '@appshell/runtime';
|
|
2
4
|
export type Schema = JSONSchema4 | JSONSchema6 | JSONSchema7;
|
|
3
5
|
export type ConfigValidator = {
|
|
4
6
|
validate: <T>(...config: T[]) => void;
|
|
@@ -43,58 +45,184 @@ export type ComparisonTarget = {
|
|
|
43
45
|
name: string;
|
|
44
46
|
dependencies: Record<string, string | undefined>;
|
|
45
47
|
};
|
|
48
|
+
/**
|
|
49
|
+
* Every key `appshell config set` accepts, kept adjacent to the type it must agree with.
|
|
50
|
+
*
|
|
51
|
+
* It used to live in the set handler, and adding `caFile` to CliConfig without touching it
|
|
52
|
+
* produced a setting the cli could read and refuse to write.
|
|
53
|
+
*/
|
|
54
|
+
export declare const CLI_SETTINGS: readonly ["registry", "application", "defaultScope", "authIssuer", "clientId", "apiKey", "apiKeyHeader", "caFile", "api"];
|
|
55
|
+
export type CliSetting = (typeof CLI_SETTINGS)[number];
|
|
46
56
|
export type CliConfig = Record<string, string> & {
|
|
47
57
|
apiKey: string;
|
|
58
|
+
/**
|
|
59
|
+
* PEM bundle to trust in addition to Node's built-ins, for a registry behind a private
|
|
60
|
+
* CA. Optional, and absent from `config init` output: an empty path is not a default
|
|
61
|
+
* worth writing, and its absence means "use Node's defaults".
|
|
62
|
+
*/
|
|
63
|
+
caFile?: string;
|
|
64
|
+
/**
|
|
65
|
+
* The platform api the registry's organizations live on, e.g. https://api.appshell.org.
|
|
66
|
+
* Optional: absent, `appshell org` derives it from the auth issuer's host (auth.<domain> →
|
|
67
|
+
* api.<domain>), and a registry run without a platform behind it has no organizations.
|
|
68
|
+
*/
|
|
69
|
+
api?: string;
|
|
48
70
|
registry: string;
|
|
49
|
-
|
|
50
|
-
|
|
71
|
+
application: string;
|
|
72
|
+
/**
|
|
73
|
+
* Which namespace an unqualified name belongs to, absent anything better.
|
|
74
|
+
*
|
|
75
|
+
* Addressing only, and named for it. It was `scope-id`, which read as *the scope this
|
|
76
|
+
* account has* — identity — and it is not: the registry takes a caller's scope from the
|
|
77
|
+
* token, and this value never reaches it. Publishing takes it from the package name.
|
|
78
|
+
* So a `scope-id` here decided where names resolved while something else decided where
|
|
79
|
+
* writes landed, and the two could disagree without anything saying so.
|
|
80
|
+
*
|
|
81
|
+
* It earns its place all the same: `resolveScopeId` falls back to the account's own
|
|
82
|
+
* scope and deliberately refuses to guess when an account owns several, and this is how
|
|
83
|
+
* that is settled without passing a flag to every command.
|
|
84
|
+
*/
|
|
85
|
+
defaultScope: string;
|
|
51
86
|
authIssuer: string;
|
|
52
87
|
clientId: string;
|
|
53
88
|
};
|
|
89
|
+
/**
|
|
90
|
+
* Neither `url` nor `filename`.
|
|
91
|
+
*
|
|
92
|
+
* `url` is an origin, and an origin belongs to a deployment: a package is published once
|
|
93
|
+
* and deployed many times, so a url here would freeze one environment's answer into an
|
|
94
|
+
* immutable version and make the artifact's digest depend on where it was built.
|
|
95
|
+
*
|
|
96
|
+
* `filename` was a hand-written copy of the Module Federation `filename`, which is what
|
|
97
|
+
* actually decides the file webpack emits. Two statements of one fact, and only one of
|
|
98
|
+
* them is enforced by anything.
|
|
99
|
+
*/
|
|
54
100
|
export type AppshellConfigRemote<TMetadata = Metadata> = {
|
|
55
101
|
id: string;
|
|
56
|
-
url: string;
|
|
57
|
-
filename: string;
|
|
58
102
|
metadata: TMetadata;
|
|
59
103
|
};
|
|
60
104
|
export type AppshellConfig<TMetadata = Metadata> = {
|
|
61
105
|
name?: string;
|
|
62
|
-
|
|
63
|
-
|
|
106
|
+
/**
|
|
107
|
+
* What the registry should publish this package as. `--visibility` overrides it.
|
|
108
|
+
*
|
|
109
|
+
* Declared here but deliberately absent from the manifest, as `name` already is: the
|
|
110
|
+
* manifest is hashed into the package digest, and visibility is not a property of the
|
|
111
|
+
* artifact. Keeping it out is what lets a package be made public later without its
|
|
112
|
+
* content changing identity.
|
|
113
|
+
*/
|
|
114
|
+
visibility?: 'public' | 'private';
|
|
115
|
+
/**
|
|
116
|
+
* What this package publishes, keyed by federation entrypoint.
|
|
117
|
+
*
|
|
118
|
+
* Appshell's own word rather than a framework's. It was `remotes`, which is MF's word
|
|
119
|
+
* for the opposite — what a package consumes — so the file read inverted to anyone who
|
|
120
|
+
* knew the framework. `exposes` would fix that and put MF's vocabulary at the top level
|
|
121
|
+
* of appshell's model, which is what the loader recipe exists to prevent.
|
|
122
|
+
*/
|
|
123
|
+
components?: Record<string, AppshellConfigRemote<TMetadata>>;
|
|
124
|
+
/**
|
|
125
|
+
* What this package consumes, by the name it refers to them by.
|
|
126
|
+
*
|
|
127
|
+
* A flat list because a referenced remote is required by definition: unbound, the region
|
|
128
|
+
* renders an error. `RemoteSlot`'s `fallback` is a loading placeholder — it shows while
|
|
129
|
+
* the remote arrives, not when it is absent — so unlike a design token's `var()`
|
|
130
|
+
* fallback it describes no degraded-but-working state.
|
|
131
|
+
*
|
|
132
|
+
* The application binds each name to a registry address, so a package never states the
|
|
133
|
+
* scope its siblings were published into — which it cannot know, since scope is assigned
|
|
134
|
+
* by whoever publishes.
|
|
135
|
+
*/
|
|
136
|
+
remotes?: string[];
|
|
137
|
+
vars?: Record<string, unknown>;
|
|
64
138
|
overrides?: AppshellOverrides;
|
|
65
139
|
};
|
|
66
140
|
export type AppshellTemplate<TMetadata = Metadata> = {
|
|
67
141
|
name?: string;
|
|
68
|
-
|
|
142
|
+
/** Carried from the yaml for publish to read; never mapped into the manifest. */
|
|
143
|
+
visibility?: 'public' | 'private';
|
|
144
|
+
components?: Record<string, AppshellConfigRemote<TMetadata>>;
|
|
145
|
+
remotes?: string[];
|
|
69
146
|
module: ModuleFederationPluginOptions;
|
|
70
|
-
|
|
147
|
+
vars?: Record<string, unknown>;
|
|
148
|
+
tokens?: Record<string, AppshellTokenUsage>;
|
|
71
149
|
overrides?: AppshellOverrides;
|
|
72
150
|
};
|
|
73
151
|
/** Appshell manifest types */
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
scope: string;
|
|
79
|
-
module: string;
|
|
80
|
-
shareScope?: string;
|
|
81
|
-
metadata: TMetadata;
|
|
152
|
+
/** The parts of a remote an application may point somewhere else. */
|
|
153
|
+
export type RemoteOverride = {
|
|
154
|
+
remoteEntryUrl?: string;
|
|
155
|
+
manifestUrl?: string;
|
|
82
156
|
};
|
|
83
157
|
export type AppshellOverrides = {
|
|
84
|
-
|
|
158
|
+
vars: Record<string, Record<string, string | number | undefined>>;
|
|
159
|
+
/**
|
|
160
|
+
* Where an application loads a remote from, keyed by registry address.
|
|
161
|
+
*
|
|
162
|
+
* A package is published once; an application is deployed many times, per environment.
|
|
163
|
+
* The origin a bundle is served from is a property of a deployment, so it belongs to
|
|
164
|
+
* whoever deploys rather than being frozen into an immutable artifact at publish — which
|
|
165
|
+
* is also what makes adopting someone else's package and serving it yourself a spec edit
|
|
166
|
+
* rather than a republish.
|
|
167
|
+
*
|
|
168
|
+
* `filename` stays in the manifest: `remoteEntry.js` is genuinely build output. Only the
|
|
169
|
+
* origin varies by environment.
|
|
170
|
+
*/
|
|
171
|
+
remotes?: Record<string, RemoteOverride>;
|
|
172
|
+
};
|
|
173
|
+
/**
|
|
174
|
+
* Which design tokens a package's own output reaches for. Observed from the emitted
|
|
175
|
+
* assets rather than declared: the CSS already says it, and a hand-kept list is a copy
|
|
176
|
+
* that drifts the first time someone adds a token and forgets the yaml.
|
|
177
|
+
*
|
|
178
|
+
* `required` is a reference with no fallback — the package has no plan B. `optional` is
|
|
179
|
+
* `var(--appshell-x, something)`, which degrades on its own. That split is read off what
|
|
180
|
+
* the author wrote rather than asked of them.
|
|
181
|
+
*/
|
|
182
|
+
export type AppshellTokenUsage = {
|
|
183
|
+
required: string[];
|
|
184
|
+
optional: string[];
|
|
185
|
+
};
|
|
186
|
+
/** A shared-dependency contract, named as one framework's model among possible models. */
|
|
187
|
+
export type SharedContract = {
|
|
188
|
+
apiVersion: 'federation.appshell.org/v1';
|
|
189
|
+
kind: 'ModuleFederation';
|
|
190
|
+
/** Keyed by share scope, as Module Federation groups them. */
|
|
191
|
+
scopes: Record<string, SharedObject>;
|
|
85
192
|
};
|
|
86
193
|
export type AppshellManifest<TMetadata = Metadata> = {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
194
|
+
/** What this package publishes, keyed by federation entrypoint. */
|
|
195
|
+
components: Record<string, PublishedRemote<TMetadata>>;
|
|
196
|
+
/** What it consumes, by local name; the application binds each to an address. */
|
|
197
|
+
remotes?: string[];
|
|
198
|
+
/**
|
|
199
|
+
* The shared-dependency contract this package was built against.
|
|
200
|
+
*
|
|
201
|
+
* Tagged like the loader recipe, and for the same reason: share scopes, singletons and
|
|
202
|
+
* version ranges are Module Federation's model of the problem, which single-spa and
|
|
203
|
+
* import maps solve differently. This replaced `modules`, which stored MF's plugin
|
|
204
|
+
* options verbatim — one reader took two fields from it, while its source paths and
|
|
205
|
+
* type-generation flags sat inside the package digest.
|
|
206
|
+
*/
|
|
207
|
+
shared?: SharedContract;
|
|
208
|
+
vars: Record<string, Record<string, string | number | undefined>>;
|
|
209
|
+
/** Keyed by federation scope, so a merged manifest still says which package needs what. */
|
|
210
|
+
tokens?: Record<string, AppshellTokenUsage>;
|
|
90
211
|
overrides?: AppshellOverrides;
|
|
91
212
|
};
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
213
|
+
/**
|
|
214
|
+
* A remote as a package publishes it: what the build knows about itself, and nothing
|
|
215
|
+
* about where it ends up.
|
|
216
|
+
*
|
|
217
|
+
* Distinct from `AppshellRemote`, which is the same remote after the registry has
|
|
218
|
+
* resolved it for the browser. They were one type, which is why the origin ended up in
|
|
219
|
+
* the artifact: the browser genuinely needs a url, so the published form appeared to as
|
|
220
|
+
* well. The registry supplies it at composition, from the address and its serving plane.
|
|
221
|
+
*/
|
|
222
|
+
export type PublishedRemote<TMetadata = Metadata> = {
|
|
223
|
+
id: string;
|
|
224
|
+
loader: RemoteLoader;
|
|
225
|
+
metadata: TMetadata;
|
|
98
226
|
};
|
|
99
227
|
/** An `AppshellRemote` the registry already resolved, so the browser needs no manifest fetch. */
|
|
100
228
|
export type ResolvedRemote<TMetadata = Metadata> = AppshellRemote<TMetadata>;
|
|
@@ -102,19 +230,45 @@ export type ResolvedRemote<TMetadata = Metadata> = AppshellRemote<TMetadata>;
|
|
|
102
230
|
* The wire contract for `window.__appshell_config__`. Deliberately not an
|
|
103
231
|
* `AppshellManifest`: that is a build artifact, and reusing it left it unclear
|
|
104
232
|
* which fields the browser actually needs. `modules` is build-time webpack
|
|
105
|
-
* config and never crosses the wire; `
|
|
106
|
-
*
|
|
233
|
+
* config and never crosses the wire; `vars` arrives already merged with the
|
|
234
|
+
* application's overrides, leaving the browser only local overrides to apply.
|
|
107
235
|
*/
|
|
108
236
|
export type AppshellComposition<TMetadata = Metadata> = {
|
|
109
237
|
/** `scope/name` — makes the payload self-describing for fetch-on-miss and for `env diff`. */
|
|
110
|
-
|
|
238
|
+
applicationId: string;
|
|
111
239
|
revision: number;
|
|
112
240
|
/** The remote key the host mounts at the root, and the props it is given. */
|
|
113
241
|
root: string;
|
|
114
242
|
rootProps: Record<string, unknown>;
|
|
115
243
|
index: AppshellIndex;
|
|
116
244
|
remotes: Record<string, ResolvedRemote<TMetadata>>;
|
|
117
|
-
|
|
245
|
+
vars: Record<string, Record<string, string | number | undefined>>;
|
|
246
|
+
/**
|
|
247
|
+
* Present whenever a per-developer overlay changed anything about this render — a
|
|
248
|
+
* redirected remote, a different shell bundle, a substituted theme, or any combination.
|
|
249
|
+
* The shell is expected to surface it: a page that quietly runs code from somewhere
|
|
250
|
+
* else is the one thing this feature must never be, and swapping the shell or the theme
|
|
251
|
+
* out counts.
|
|
252
|
+
*
|
|
253
|
+
* `shellFlavor` is what was actually served, not what was asked for. `theme` is the ref
|
|
254
|
+
* the overlay substituted, present only when it substituted one.
|
|
255
|
+
*/
|
|
256
|
+
overlay?: {
|
|
257
|
+
id: string;
|
|
258
|
+
remotes: string[];
|
|
259
|
+
/**
|
|
260
|
+
* Those of `remotes` the overlay introduced rather than redirected — components the
|
|
261
|
+
* application does not publish, running for this developer and nobody else.
|
|
262
|
+
*
|
|
263
|
+
* Separate from `remotes` because the two are not the same claim. A redirected
|
|
264
|
+
* component exists for everyone and this browser runs a different copy of it; an
|
|
265
|
+
* added one does not exist outside this overlay at all, so a feature built on top of
|
|
266
|
+
* one works here and is absent everywhere else.
|
|
267
|
+
*/
|
|
268
|
+
added?: string[];
|
|
269
|
+
shellFlavor: 'prod' | 'dev';
|
|
270
|
+
theme?: string;
|
|
271
|
+
};
|
|
118
272
|
};
|
|
119
273
|
/**
|
|
120
274
|
* Advanced configuration for modules that should be exposed by this container.
|
|
@@ -293,4 +447,3 @@ export interface ModuleFederationPluginOptions {
|
|
|
293
447
|
*/
|
|
294
448
|
shared?: (string | SharedObject)[] | SharedObject;
|
|
295
449
|
}
|
|
296
|
-
//# sourceMappingURL=types.d.ts.map
|
|
@@ -5,4 +5,3 @@ export declare const compareDependencies: (sample: ComparisonTarget, baseline: C
|
|
|
5
5
|
export declare const compareSharedDependencies: (packageSpec: PackageSpec, sharedModule: SharedModuleSpec) => ComparisonResults;
|
|
6
6
|
export declare const compareSharedModules: (sampleSpec: SharedModuleSpec, baselineSpec: SharedModuleSpec) => ComparisonResults;
|
|
7
7
|
export declare const printResults: (results: ComparisonResults) => void;
|
|
8
|
-
//# sourceMappingURL=compare.d.ts.map
|
|
@@ -1,6 +1,20 @@
|
|
|
1
1
|
import yargs from 'yargs';
|
|
2
2
|
import { CliConfig } from '../types';
|
|
3
|
+
/**
|
|
4
|
+
* The addressing default: which namespace an unqualified name resolves to.
|
|
5
|
+
*
|
|
6
|
+
* Named `default-scope` and not `scope-id`, because the old name described identity —
|
|
7
|
+
* *the scope this account has* — and the value has never been that. The registry takes a
|
|
8
|
+
* caller's scope from the token and publishing takes it from the package name; this
|
|
9
|
+
* reaches neither. A `scope-id` deciding where names resolved while something else decided
|
|
10
|
+
* where writes landed is how the two came to disagree without anything saying so.
|
|
11
|
+
*
|
|
12
|
+
* Stated once because the cli and the webpack plugin both need the answer, and two
|
|
13
|
+
* precedence chains for one setting is how they drift apart.
|
|
14
|
+
*/
|
|
15
|
+
export declare const resolveDefaultScope: (config: {
|
|
16
|
+
defaultScope?: string;
|
|
17
|
+
}, env?: NodeJS.ProcessEnv) => string | undefined;
|
|
3
18
|
export declare const readConfig: (configPath: string) => CliConfig;
|
|
4
19
|
export declare const writeConfig: (configPath: string, config: CliConfig) => void;
|
|
5
20
|
export declare const mergeConfigWithArgs: (config: CliConfig, argv: yargs.ArgumentsCamelCase<unknown>) => void;
|
|
6
|
-
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Serialises a value to YAML.
|
|
3
|
+
*
|
|
4
|
+
* The counterpart to `load`, and here rather than at each call site so the YAML library
|
|
5
|
+
* stays in one package. `appshell theme init` writes a file an author then edits, so the
|
|
6
|
+
* output is line-wrapped generously — a colour value broken across lines is technically
|
|
7
|
+
* valid and horrible to read.
|
|
8
|
+
*/
|
|
9
|
+
declare const dump: (value: unknown) => string;
|
|
10
|
+
export default dump;
|
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
export { default as blur } from './blur';
|
|
2
2
|
export { compareDependencies, compareDependency, compareSharedDependencies, compareSharedModules, extractDependencies, printResults, } from './compare';
|
|
3
|
-
export { mergeConfigWithArgs, readConfig, writeConfig } from './config';
|
|
3
|
+
export { mergeConfigWithArgs, readConfig, resolveDefaultScope, writeConfig } from './config';
|
|
4
4
|
export { default as copy } from './copy';
|
|
5
|
-
export { default as
|
|
5
|
+
export { default as dump } from './dump';
|
|
6
6
|
export { default as list } from './list';
|
|
7
7
|
export { default as load, loadAll } from './load';
|
|
8
|
-
export { default as loadJson } from './loadJson';
|
|
9
|
-
export { default as merge } from './merge';
|
|
10
|
-
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1,4 +1 @@
|
|
|
1
|
-
export { default as AppshellGlobalConfigValidator } from './AppshellGlobalConfigValidator';
|
|
2
|
-
export { default as AppshellManifestValidator } from './AppshellManifestValidator';
|
|
3
1
|
export { default as AppshellTemplateValidator } from './AppshellTemplateValidator';
|
|
4
|
-
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
export default
|
|
14
|
-
//# sourceMappingURL=loadAppshellComponent.d.ts.map
|
|
1
|
+
import type { RemoteLoader } from '@appshell/runtime';
|
|
2
|
+
/**
|
|
3
|
+
* Dispatches on the loader's kind rather than assuming federation.
|
|
4
|
+
*
|
|
5
|
+
* There is one kind today. Naming it is what lets a second — single-spa, import maps —
|
|
6
|
+
* arrive without reinterpreting manifests already published, and what stops federation's
|
|
7
|
+
* vocabulary reading as though it were appshell's.
|
|
8
|
+
*/
|
|
9
|
+
export declare const load: <TComponent>(remote: {
|
|
10
|
+
loader: RemoteLoader;
|
|
11
|
+
remoteEntryUrl: string;
|
|
12
|
+
}) => Promise<TComponent>;
|
|
13
|
+
export default load;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AppshellComposition
|
|
1
|
+
import type { AppshellComposition } from '@appshell/config';
|
|
2
2
|
import { type RemoteResolver } from './resolvers';
|
|
3
3
|
declare global {
|
|
4
4
|
interface Window {
|
|
@@ -10,6 +10,5 @@ export type RemoteLoaderOptions = {
|
|
|
10
10
|
/** Replaces the resolver chain outright; a seam for tests and embedders. */
|
|
11
11
|
resolver?: RemoteResolver;
|
|
12
12
|
};
|
|
13
|
-
declare const _default: (
|
|
13
|
+
declare const _default: (options?: RemoteLoaderOptions) => <TComponent>(key: string) => Promise<readonly [Awaited<TComponent>, import("@appshell/config").ResolvedRemote]>;
|
|
14
14
|
export default _default;
|
|
15
|
-
//# sourceMappingURL=remoteLoader.d.ts.map
|
|
@@ -1,20 +1,12 @@
|
|
|
1
|
-
import type { AppshellComposition,
|
|
1
|
+
import type { AppshellComposition, ResolvedRemote } from '@appshell/config';
|
|
2
2
|
export type RemoteResolution = {
|
|
3
3
|
remote: ResolvedRemote;
|
|
4
|
-
/** Already merged with the
|
|
5
|
-
|
|
6
|
-
/** Back-compat payload for `ManifestProvider`; synthesized when the source was a composition. */
|
|
7
|
-
manifest: AppshellManifest;
|
|
4
|
+
/** Already merged with the application's overrides — nothing left for the browser to layer on. */
|
|
5
|
+
vars: Record<string, string | number | undefined>;
|
|
8
6
|
};
|
|
9
7
|
export type RemoteResolver = (key: string) => Promise<RemoteResolution | undefined>;
|
|
10
8
|
/** The registry inlined the composition into the page, so no network call is needed. */
|
|
11
9
|
export declare const inlineResolver: (composition?: AppshellComposition) => RemoteResolver;
|
|
12
|
-
/** Fetch-on-miss: covers
|
|
10
|
+
/** Fetch-on-miss: covers a package activated after this page was served. */
|
|
13
11
|
export declare const registryResolver: (composition?: AppshellComposition, origin?: string) => RemoteResolver;
|
|
14
|
-
/**
|
|
15
|
-
* Pre-registry hosts: follow `index[key]` to the app's own manifest. The override
|
|
16
|
-
* merge stays here because in this mode no server has done it.
|
|
17
|
-
*/
|
|
18
|
-
export declare const legacyManifestResolver: (config: AppshellGlobalConfig) => RemoteResolver;
|
|
19
12
|
export declare const chainResolvers: (...resolvers: RemoteResolver[]) => RemoteResolver;
|
|
20
|
-
//# sourceMappingURL=resolvers.d.ts.map
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { ReactElement, ReactNode } from 'react';
|
|
2
|
+
export type ExtendedProps = Record<string, unknown>;
|
|
3
|
+
export type RemoteSlotProps<TProps extends ExtendedProps = ExtendedProps> = {
|
|
4
|
+
remote: string;
|
|
5
|
+
fallback?: ReactNode;
|
|
6
|
+
} & TProps;
|
|
7
|
+
/**
|
|
8
|
+
* Loads a remote once and leaves it alone.
|
|
9
|
+
*
|
|
10
|
+
* Keeping a remote current while it is being developed is not this component's job.
|
|
11
|
+
* A remote served by a dev server ships webpack's HMR runtime and a dev-server client
|
|
12
|
+
* inside its own `remoteEntry`, so it applies its own edits in place and React Fast
|
|
13
|
+
* Refresh swaps the component implementations underneath this tree — no reload, and no
|
|
14
|
+
* remount that would discard state this component never owned.
|
|
15
|
+
*
|
|
16
|
+
* Watching the remote's socket from here and reloading the page was strictly worse: it
|
|
17
|
+
* raced the remote's own update, and it threw away the entire composed app to deliver a
|
|
18
|
+
* change to one subtree. When webpack genuinely cannot apply an update, the remote's own
|
|
19
|
+
* client still falls back to a full reload — which is the right place for that decision,
|
|
20
|
+
* because it is the only side that knows whether the update applied.
|
|
21
|
+
*/
|
|
22
|
+
declare const RemoteSlot: {
|
|
23
|
+
<TProps extends ExtendedProps>({ remote, fallback, ...rest }: RemoteSlotProps<TProps>): ReactElement<TProps>;
|
|
24
|
+
defaultProps: {
|
|
25
|
+
fallback: undefined;
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
export default RemoteSlot;
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import { AppshellRemote } from '@appshell/config';
|
|
2
2
|
import type { FC, ReactNode } from 'react';
|
|
3
|
-
import React from 'react';
|
|
4
3
|
interface RemoteProviderProps {
|
|
5
4
|
remote?: AppshellRemote;
|
|
6
5
|
children: ReactNode;
|
|
7
6
|
}
|
|
8
|
-
export declare const RemoteContext:
|
|
7
|
+
export declare const RemoteContext: import("react").Context<AppshellRemote | undefined>;
|
|
9
8
|
export declare const RemoteProvider: FC<RemoteProviderProps>;
|
|
10
|
-
export declare const RemoteConsumer:
|
|
9
|
+
export declare const RemoteConsumer: import("react").Consumer<AppshellRemote | undefined>;
|
|
11
10
|
export default RemoteContext;
|
|
12
|
-
//# sourceMappingURL=RemoteContext.d.ts.map
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { AppshellRemote } from '@appshell/config';
|
|
2
|
-
/** The remote backing the nearest `
|
|
2
|
+
/** The remote backing the nearest `RemoteSlot` — it already knows its own key. */
|
|
3
3
|
declare const _default: () => AppshellRemote | undefined;
|
|
4
4
|
export default _default;
|
|
5
|
-
//# sourceMappingURL=useRemote.d.ts.map
|