@bleedingdev/modern-js-surface-resolution 0.0.0 → 3.9.0-ultramodern.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. package/LICENSE +21 -0
  2. package/dist/cjs/surface-resolution/env-static-provider.js +318 -0
  3. package/dist/cjs/surface-resolution/index.js +69 -0
  4. package/dist/cjs/surface-resolution/surface-ref.js +132 -0
  5. package/dist/cjs/surface-resolution/types.js +18 -0
  6. package/dist/cjs/surface-resolution/validation.js +202 -0
  7. package/dist/esm/surface-resolution/env-static-provider.mjs +274 -0
  8. package/dist/esm/surface-resolution/index.mjs +3 -0
  9. package/dist/esm/surface-resolution/surface-ref.mjs +88 -0
  10. package/dist/esm/surface-resolution/types.mjs +0 -0
  11. package/dist/esm/surface-resolution/validation.mjs +155 -0
  12. package/dist/esm-node/surface-resolution/env-static-provider.mjs +275 -0
  13. package/dist/esm-node/surface-resolution/index.mjs +4 -0
  14. package/dist/esm-node/surface-resolution/surface-ref.mjs +89 -0
  15. package/dist/esm-node/surface-resolution/types.mjs +1 -0
  16. package/dist/esm-node/surface-resolution/validation.mjs +156 -0
  17. package/dist/types/surface-resolution/env-static-provider.d.ts +107 -0
  18. package/dist/types/surface-resolution/index.d.ts +4 -0
  19. package/dist/types/surface-resolution/surface-ref.d.ts +72 -0
  20. package/dist/types/surface-resolution/types.d.ts +102 -0
  21. package/dist/types/surface-resolution/validation.d.ts +53 -0
  22. package/package.json +40 -4
  23. package/src/surface-resolution/env-static-provider.ts +596 -0
  24. package/src/surface-resolution/index.ts +43 -0
  25. package/src/surface-resolution/surface-ref.ts +145 -0
  26. package/src/surface-resolution/types.ts +136 -0
  27. package/src/surface-resolution/validation.ts +337 -0
  28. package/README.md +0 -3
@@ -0,0 +1,107 @@
1
+ import type { EnvironmentId, ResolvedSurfaceKind, SurfaceResolutionProvider } from './types.js';
2
+ export type EnvRecord = Record<string, string | undefined>;
3
+ /** Which platforms a surface publishes, plus their static (non-env) inputs. */
4
+ export type EnvStaticSurfacePlatforms = {
5
+ /** Publish a `browser-mf-manifest` location (env/public/cloudflare/localhost chain). */
6
+ browserMfManifest?: boolean;
7
+ /** Publish a `node-mf-manifest` location (backend manifest env / localhost chain). */
8
+ nodeMfManifest?: boolean;
9
+ /** Publish an `http-api` location; the base URL follows the public-URL chain. */
10
+ httpApi?: {
11
+ prefix: string;
12
+ };
13
+ /** Publish a `cloudflare-service-binding` location (statically provisioned). */
14
+ cloudflareServiceBinding?: {
15
+ serviceBinding: string;
16
+ dispatchNamespace?: string;
17
+ };
18
+ };
19
+ export type EnvStaticSurfaceConfig = {
20
+ surfaceId: string;
21
+ kind: ResolvedSurfaceKind;
22
+ platforms: EnvStaticSurfacePlatforms;
23
+ };
24
+ /**
25
+ * Static configuration for one delivery unit. Identity comes from the build
26
+ * artifact (never from the environment); the environment only overrides
27
+ * addresses through the documented env-var chains.
28
+ */
29
+ export type EnvStaticUnitConfig = {
30
+ unitId: string;
31
+ buildMarker: string;
32
+ sourceRevision: string;
33
+ baselineCohortId: string;
34
+ /**
35
+ * Env-var segment, e.g. `CHECKOUT` in `VERTICAL_CHECKOUT_MF_MANIFEST` /
36
+ * `ULTRAMODERN_PUBLIC_URL_CHECKOUT` (`toEnvSegment(domain ?? id)`).
37
+ */
38
+ envSegment: string;
39
+ /** Module-federation container name (used to strip `mfName@` env prefixes). */
40
+ mfName: string;
41
+ /** Localhost dev fallback port. Without it, env values are mandatory. */
42
+ port?: number;
43
+ /** Cloudflare worker name for the workers.dev fallback. */
44
+ workerName?: string;
45
+ /**
46
+ * Externally published majors (ADR-0020), each with its own materialization.
47
+ * A requested `@vN` resolves ONLY through the matching entry; a major that
48
+ * is not configured here is the typed `major-not-published` error.
49
+ */
50
+ majors?: EnvStaticMajorConfig[];
51
+ surfaces: EnvStaticSurfaceConfig[];
52
+ };
53
+ /**
54
+ * Per-major materialization (ADR-0020): where the externally published major
55
+ * `vN` of a unit lives. Address inputs are deliberately NOT inherited from the
56
+ * unversioned unit — a versioned request must never be answered with
57
+ * unversioned locations — so each major carries its own env segment (default
58
+ * `${unit.envSegment}_V${major}`) and, optionally, its own localhost port /
59
+ * worker name.
60
+ */
61
+ export type EnvStaticMajorConfig = {
62
+ major: number;
63
+ /** Env-var segment for this major. Default: `${unit.envSegment}_V${major}`. */
64
+ envSegment?: string;
65
+ /** Localhost dev fallback port for this major (local environments only). */
66
+ port?: number;
67
+ /** Cloudflare worker name for this major's workers.dev fallback. */
68
+ workerName?: string;
69
+ };
70
+ /**
71
+ * How the provider's stamped identity is to be interpreted. `static-trust`
72
+ * (the only mode, and the default) means identity is asserted from static
73
+ * config, not verified against the artifacts; the compatibility verdict then
74
+ * carries `reason: 'static-identity-unverified'`.
75
+ */
76
+ export type EnvStaticIdentityVerification = 'static-trust';
77
+ /** Environments in which localhost dev fallbacks are allowed by default. */
78
+ export declare const DEFAULT_LOCAL_ENVIRONMENTS: readonly string[];
79
+ export type EnvStaticProviderOptions = {
80
+ units: EnvStaticUnitConfig[];
81
+ /**
82
+ * Environment record to read from. Universal module: `process.env` is never
83
+ * read implicitly; pass it explicitly in Node hosts.
84
+ */
85
+ env?: EnvRecord;
86
+ /**
87
+ * Environments in which localhost dev fallbacks apply. Any environment NOT
88
+ * listed here fails closed: missing explicit configuration is the typed
89
+ * `provider-unavailable` error, never a localhost URL.
90
+ * Default: `['development', 'local']`.
91
+ */
92
+ localEnvironments?: EnvironmentId[];
93
+ /**
94
+ * Identity-honesty mode (ADR-0019). Default `'static-trust'`: the verdict
95
+ * is marked `static-identity-unverified` because this provider asserts
96
+ * identity from static config without verifying the resolved artifacts.
97
+ */
98
+ identityVerification?: EnvStaticIdentityVerification;
99
+ };
100
+ export declare const ENV_STATIC_PROVIDER_NAME = "env-static";
101
+ /**
102
+ * Create the baseline env/static provider. Resolution is all-or-nothing per
103
+ * RESOLUTION-0001: every declared platform location for every surface of the
104
+ * unit assembles against the unit's single static identity, or the whole
105
+ * resolution fails with one typed error.
106
+ */
107
+ export declare function createEnvStaticSurfaceResolutionProvider(options: EnvStaticProviderOptions): SurfaceResolutionProvider;
@@ -0,0 +1,4 @@
1
+ export { createEnvStaticSurfaceResolutionProvider, DEFAULT_LOCAL_ENVIRONMENTS, ENV_STATIC_PROVIDER_NAME, type EnvRecord, type EnvStaticIdentityVerification, type EnvStaticMajorConfig, type EnvStaticProviderOptions, type EnvStaticSurfaceConfig, type EnvStaticSurfacePlatforms, type EnvStaticUnitConfig, } from './env-static-provider.js';
2
+ export { formatSurfaceRef, type ParsedSurfaceRef, parseSurfaceRef, type SurfaceRefParseError, type SurfaceRefParseResult, validateSurfaceRef, } from './surface-ref.js';
3
+ export type { CompatibilityStatus, CompatibilityVerdict, DiscoveryError, DiscoveryErrorCode, DiscoveryResult, EnvironmentId, ResolvedDeliveryUnit, ResolvedSurface, ResolvedSurfaceKind, ResolvedSurfaceLocation, ResolvedSurfaceLocationPlatform, SurfaceResolutionProvider, } from './types.js';
4
+ export { createDiscoveryError, type ExpectedDeliveryUnitIdentity, matchDeliveryUnitIdentity, type ResolvedDeliveryUnitIssue, type ResolvedDeliveryUnitValidationResult, selectResolvedSurface, validateResolvedDeliveryUnit, } from './validation.js';
@@ -0,0 +1,72 @@
1
+ /**
2
+ * SurfaceRef grammar (MV-G25a).
3
+ *
4
+ * Mirrors the EBNF in `packages/toolkit/create/delivery-unit-schema-SPEC.md` §2
5
+ * exactly:
6
+ *
7
+ * ```ebnf
8
+ * SurfaceRef = UnitId , "#" , SurfaceId , [ "@" , Major ] ;
9
+ * UnitId = Segment , { "/" , Segment } ;
10
+ * SurfaceId = Segment ;
11
+ * Segment = SegmentChar , { SegmentChar } ;
12
+ * SegmentChar = letter | digit | "-" | "_" | "." ;
13
+ * Major = "v" , nonzero , { digit } ;
14
+ * ```
15
+ *
16
+ * Canonical form: `unitId#surfaceId` with optional `@vN` external-major suffix
17
+ * (e.g. `acme/checkout#cart`, `acme/checkout#cart@v2`). Universal module:
18
+ * dependency-free, runs in any JavaScript environment.
19
+ */
20
+ /**
21
+ * Parsed form of a SurfaceRef. Canonical string form is `unitId#surfaceId`
22
+ * with an optional `@vN` major suffix.
23
+ */
24
+ export type ParsedSurfaceRef = {
25
+ unitId: string;
26
+ surfaceId: string;
27
+ /** External-major selector. Absent means "the coordinated-zone surface". */
28
+ major?: number;
29
+ };
30
+ export type SurfaceRefParseError = {
31
+ code: 'empty';
32
+ } | {
33
+ code: 'missing-surface-separator';
34
+ } | {
35
+ code: 'multiple-surface-separators';
36
+ } | {
37
+ code: 'empty-unit-id';
38
+ } | {
39
+ code: 'invalid-unit-id';
40
+ segment: string;
41
+ } | {
42
+ code: 'empty-surface-id';
43
+ } | {
44
+ code: 'invalid-surface-id';
45
+ } | {
46
+ code: 'empty-major';
47
+ } | {
48
+ code: 'invalid-major';
49
+ value: string;
50
+ };
51
+ export type SurfaceRefParseResult = {
52
+ ok: true;
53
+ ref: ParsedSurfaceRef;
54
+ } | {
55
+ ok: false;
56
+ error: SurfaceRefParseError;
57
+ };
58
+ /**
59
+ * Parse a canonical SurfaceRef string. Total function: every rejection is a
60
+ * typed {@link SurfaceRefParseError}; never throws.
61
+ */
62
+ export declare function parseSurfaceRef(input: string): SurfaceRefParseResult;
63
+ /**
64
+ * Render a {@link ParsedSurfaceRef} back to its canonical string form.
65
+ *
66
+ * Direct inputs are checked against the same invariant as parsed references,
67
+ * so this formatter cannot emit a string that {@link parseSurfaceRef} rejects.
68
+ * Round-trip: `formatSurfaceRef(parseSurfaceRef(x).ref) === x` for valid `x`.
69
+ */
70
+ export declare function formatSurfaceRef(ref: ParsedSurfaceRef): string;
71
+ /** The shared semantic invariant for parsed and directly formatted references. */
72
+ export declare function validateSurfaceRef(ref: ParsedSurfaceRef): SurfaceRefParseError | undefined;
@@ -0,0 +1,102 @@
1
+ /**
2
+ * Surface-resolution record + provider SPI (MV-G25b/c).
3
+ *
4
+ * Contract: `docs/super-app-rfc-adr/RESOLUTION-0001-surface-discovery-record.md`.
5
+ * Discovery answers a SurfaceRef with exactly ONE {@link ResolvedDeliveryUnit}
6
+ * — never a bare URL, never a partial set of locations — or a typed
7
+ * {@link DiscoveryError} (§2.4: discovery errors are expected states, not
8
+ * exceptions).
9
+ *
10
+ * Atomicity invariant (ADR-0019): `buildMarker` / `sourceRevision` /
11
+ * `baselineCohortId` live once on the record; a {@link ResolvedSurface}
12
+ * carries no marker of its own, so mixing locations from two build markers is
13
+ * structurally unrepresentable.
14
+ */
15
+ import type { DeliveryUnitIdentity } from '@modern-js/backend-federation-contracts';
16
+ import type { ParsedSurfaceRef } from './surface-ref.js';
17
+ export type ResolvedSurfaceLocationPlatform = 'browser-mf-manifest' | 'node-mf-manifest' | 'http-api' | 'cloudflare-service-binding';
18
+ /**
19
+ * One platform address for a surface, discriminated on `platform` so each
20
+ * platform carries only the address shape its execution adapter can load.
21
+ */
22
+ export type ResolvedSurfaceLocation = {
23
+ platform: 'browser-mf-manifest';
24
+ manifestUrl: string;
25
+ } | {
26
+ /** Backend `backend-mf-manifest.json` URL or filesystem path. */
27
+ platform: 'node-mf-manifest';
28
+ manifestRef: string;
29
+ } | {
30
+ platform: 'http-api';
31
+ baseUrl: string;
32
+ prefix: string;
33
+ } | {
34
+ platform: 'cloudflare-service-binding';
35
+ serviceBinding: string;
36
+ dispatchNamespace?: string;
37
+ };
38
+ export type ResolvedSurfaceKind = 'component' | 'route' | 'api' | 'backend';
39
+ /**
40
+ * A resolved surface. It carries NO build marker of its own: the marker lives
41
+ * once on the {@link ResolvedDeliveryUnit} (ADR-0019 structural atomicity).
42
+ */
43
+ export type ResolvedSurface = {
44
+ surfaceId: string;
45
+ kind: ResolvedSurfaceKind;
46
+ locations: ResolvedSurfaceLocation[];
47
+ /**
48
+ * The external major (ADR-0020) this materialization serves. Present exactly
49
+ * when the record answers a versioned SurfaceRef (`…@vN`): the locations are
50
+ * the major-specific materialization, never the unversioned addresses.
51
+ */
52
+ servedMajor?: number;
53
+ };
54
+ export type CompatibilityStatus = 'compatible' | 'incompatible' | 'degraded';
55
+ /** The resolver's verdict, not the consumer's guess (RESOLUTION-0001 §2.1). */
56
+ export type CompatibilityVerdict = {
57
+ status: CompatibilityStatus;
58
+ /** Baseline cohort id the verdict was computed against. */
59
+ baselineCohortId: string;
60
+ reason?: string;
61
+ };
62
+ /**
63
+ * Atomic resolution result: every platform location for the unit, resolved
64
+ * together against ONE `buildMarker` / `sourceRevision`. There is no partial
65
+ * variant; a resolver returns this whole record or a {@link DiscoveryError}.
66
+ */
67
+ export type ResolvedDeliveryUnit = DeliveryUnitIdentity & {
68
+ baselineCohortId: string;
69
+ surfaces: ResolvedSurface[];
70
+ compatibility: CompatibilityVerdict;
71
+ };
72
+ export type DiscoveryErrorCode = 'unknown-unit' | 'unknown-surface' | 'major-not-published' | 'identity-mismatch' | 'stale-record' | 'provider-unavailable';
73
+ export type DiscoveryError = {
74
+ code: DiscoveryErrorCode;
75
+ /** Canonical string form of the SurfaceRef being resolved. */
76
+ ref: string;
77
+ message: string;
78
+ details?: Record<string, unknown>;
79
+ };
80
+ export type DiscoveryResult = {
81
+ ok: true;
82
+ unit: ResolvedDeliveryUnit;
83
+ } | {
84
+ ok: false;
85
+ error: DiscoveryError;
86
+ };
87
+ /**
88
+ * Environment identity. Providers are selected per environment, not per
89
+ * surface: one environment resolves all surfaces of a unit through the same
90
+ * provider chain.
91
+ */
92
+ export type EnvironmentId = string;
93
+ export type SurfaceResolutionProvider = {
94
+ /** Stable provider name (e.g. `env-static`), used in error details. */
95
+ name: string;
96
+ /**
97
+ * Resolve a SurfaceRef in an environment to one complete record or one
98
+ * typed error. Must never return a partial record and must never mix
99
+ * locations from different build markers.
100
+ */
101
+ resolve(ref: ParsedSurfaceRef, env: EnvironmentId): DiscoveryResult | Promise<DiscoveryResult>;
102
+ };
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Identity / compatibility validation helpers for resolved delivery units
3
+ * (MV-G25c). Runtime checks for records that crossed a serialization boundary;
4
+ * within TypeScript the atomicity invariant is already structural.
5
+ */
6
+ import { type ParsedSurfaceRef } from './surface-ref.js';
7
+ import type { DiscoveryError, DiscoveryErrorCode, ResolvedDeliveryUnit, ResolvedSurface } from './types.js';
8
+ export type ResolvedDeliveryUnitIssue = {
9
+ path: string;
10
+ message: string;
11
+ };
12
+ export type ResolvedDeliveryUnitValidationResult = {
13
+ ok: boolean;
14
+ issues: ResolvedDeliveryUnitIssue[];
15
+ };
16
+ /** Build a typed {@link DiscoveryError} for a reference. */
17
+ export declare function createDiscoveryError(code: DiscoveryErrorCode, ref: ParsedSurfaceRef | string, message: string, details?: Record<string, unknown>): DiscoveryError;
18
+ /**
19
+ * Validate the structural invariants of a {@link ResolvedDeliveryUnit}:
20
+ * non-empty identity root, a well-formed compatibility verdict (valid status,
21
+ * computed against the record-level baseline cohort), and per-surface
22
+ * completeness (valid unique surface ids, valid kind, at least one location,
23
+ * no duplicate platform entries, and every discriminant + required address
24
+ * field per location platform). There is no partial-success shape: any issue
25
+ * means the record is not a valid resolution.
26
+ *
27
+ * Total: never throws, even for records that crossed a serialization boundary
28
+ * with missing or malformed nested objects — every defect is a typed issue.
29
+ */
30
+ export declare function validateResolvedDeliveryUnit(unit: ResolvedDeliveryUnit): ResolvedDeliveryUnitValidationResult;
31
+ /**
32
+ * Select the surface a {@link ParsedSurfaceRef} points at within one record.
33
+ * `unknown-unit` when the record is for a different unit, `unknown-surface`
34
+ * when the unit does not publish the surface.
35
+ */
36
+ export declare function selectResolvedSurface(unit: ResolvedDeliveryUnit, ref: ParsedSurfaceRef): {
37
+ ok: true;
38
+ surface: ResolvedSurface;
39
+ } | {
40
+ ok: false;
41
+ error: DiscoveryError;
42
+ };
43
+ export type ExpectedDeliveryUnitIdentity = {
44
+ unitId: string;
45
+ buildMarker: string;
46
+ };
47
+ /**
48
+ * Compare a consumer's expected delivery-unit identity against a resolved
49
+ * record. Execution adapters must pass the record's `unitId` + `buildMarker`
50
+ * through to identity validation (RESOLUTION-0001 §2.3); a mismatch is the
51
+ * typed `identity-mismatch` discovery error.
52
+ */
53
+ export declare function matchDeliveryUnitIdentity(expected: ExpectedDeliveryUnitIdentity, unit: Pick<ResolvedDeliveryUnit, 'unitId' | 'buildMarker'>, ref: ParsedSurfaceRef | string): DiscoveryError | undefined;
package/package.json CHANGED
@@ -1,16 +1,52 @@
1
1
  {
2
2
  "name": "@bleedingdev/modern-js-surface-resolution",
3
- "version": "0.0.0",
4
- "description": "Package-name registration for the forthcoming UltraModern.js release. This setup version contains no runtime implementation.",
3
+ "version": "3.9.0-ultramodern.5",
4
+ "description": "Universal surface references, atomic discovery records, and environment-static resolution.",
5
5
  "license": "MIT",
6
6
  "repository": {
7
7
  "type": "git",
8
- "url": "git+https://github.com/BleedingDev/ultramodern.js.git"
8
+ "url": "git+https://github.com/BleedingDev/ultramodern.js.git",
9
+ "directory": "packages/toolkit/surface-resolution"
10
+ },
11
+ "main": "./dist/cjs/surface-resolution/index.js",
12
+ "module": "./dist/esm/surface-resolution/index.mjs",
13
+ "types": "./dist/types/surface-resolution/index.d.ts",
14
+ "exports": {
15
+ ".": {
16
+ "types": "./dist/types/surface-resolution/index.d.ts",
17
+ "node": {
18
+ "import": "./dist/esm-node/surface-resolution/index.mjs",
19
+ "require": "./dist/cjs/surface-resolution/index.js"
20
+ },
21
+ "default": "./dist/esm/surface-resolution/index.mjs"
22
+ }
9
23
  },
10
24
  "files": [
11
- "README.md"
25
+ "dist",
26
+ "src"
12
27
  ],
28
+ "sideEffects": false,
29
+ "dependencies": {
30
+ "@modern-js/backend-federation-contracts": "npm:@bleedingdev/modern-js-backend-federation-contracts@3.9.0-ultramodern.5"
31
+ },
32
+ "devDependencies": {
33
+ "@modern-js/tsconfig": "npm:@bleedingdev/modern-js-tsconfig@3.9.0-ultramodern.5",
34
+ "@rslib/core": "1.0.0",
35
+ "@rstest/core": "0.11.12",
36
+ "@scripts/rstest-config": "2.66.0",
37
+ "@types/node": "^26.4.1",
38
+ "@typescript/native-preview": "7.0.0-dev.20260707.2"
39
+ },
13
40
  "publishConfig": {
14
41
  "access": "public"
42
+ },
43
+ "scripts": {
44
+ "build": "rslib build",
45
+ "dev": "rslib build --watch",
46
+ "test": "rstest run"
47
+ },
48
+ "homepage": "https://github.com/BleedingDev/ultramodern.js#readme",
49
+ "bugs": {
50
+ "url": "https://github.com/BleedingDev/ultramodern.js/issues"
15
51
  }
16
52
  }