@reventlessdev/reventless-host-shell 3.0.0-alpha.73 → 3.0.0-alpha.74

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.
@@ -1 +1 @@
1
- import{G as z,H as k}from"./index-BLP8Blsh.js";import"./virtualExposes-DN39MDG_.js";import"./virtual_mf-REMOTE_ENTRY_ID___mfe_internal__reventless_host_shell__remoteEntry-_hash_-C8lRAcSv.js";import"./preload-helper-BlTxHScW.js";import"./_virtual_mf___mfe_internal__reventless_host_shell__loadShare__react_mf_2_dom_mf_1_client__loadShare__.mjs-BzAfciYp.js";import"./__virtual_mf___mfe_internal__reventless_host_shell__loadShare__react_mf_2_dom__loadShare__.mjs_commonjs-proxy-BUE6rcGI.js";import"./__virtual_mf___mfe_internal__reventless_host_shell__loadShare__react__loadShare__.mjs_commonjs-proxy-CfkhEoF5.js";import"./_virtual_mf___mfe_internal__reventless_host_shell__loadShare__react_mf_1_jsx_mf_2_runtime__loadShare__.mjs-hre-5-8f.js";import"./_virtual_mf___mfe_internal__reventless_host_shell__loadShare__react__loadShare__.mjs-CuPed97e.js";import"./_virtual_mf___mfe_internal__reventless_host_shell__loadShare__react_mf_2_dom__loadShare__.mjs-Bp_g55i_.js";class _{marshaller;serializer;deserializer;serdeContext;defaultContentType;constructor({marshaller:s,serializer:n,deserializer:l,serdeContext:c,defaultContentType:y}){this.marshaller=s,this.serializer=n,this.deserializer=l,this.serdeContext=c,this.defaultContentType=y}async serializeEventStream({eventStream:s,requestSchema:n,initialRequest:l}){const c=this.marshaller,y=n.getEventStreamMember(),S=n.getMemberSchema(y),d=this.serializer,h=this.defaultContentType,u=Symbol("initialRequestMarker"),p={async*[Symbol.asyncIterator](){if(l){const r={":event-type":{type:"string",value:"initial-request"},":message-type":{type:"string",value:"event"},":content-type":{type:"string",value:h}};d.write(n,l);const e=d.flush();yield{[u]:!0,headers:r,body:e}}for await(const r of s)yield r}};return c.serialize(p,r=>{if(r[u])return{headers:r.headers,body:r.body};let e="";for(const i in r)if(i!=="__type"){e=i;break}const{additionalHeaders:t,body:a,eventType:o,explicitPayloadContentType:m}=this.writeEventBody(e,S,r);return{headers:{":event-type":{type:"string",value:o},":message-type":{type:"string",value:"event"},":content-type":{type:"string",value:m??h},...t},body:a}})}async deserializeEventStream({response:s,responseSchema:n,initialResponseContainer:l}){const c=this.marshaller,y=n.getEventStreamMember(),d=n.getMemberSchema(y).getMemberSchemas(),h=Symbol("initialResponseMarker"),u=c.deserialize(s.body,async e=>{let t="";for(const o in e)if(o!=="__type"){t=o;break}const a=e[t].body;if(t==="initial-response"){const o=await this.deserializer.read(n,a);return delete o[y],{[h]:!0,...o}}else if(t in d){const o=d[t];if(o.isStructSchema()){const m={};let f=!1;for(const[i,g]of o.structIterator()){const{eventHeader:v,eventPayload:w}=g.getMergedTraits();if(f=f||!!(v||w),w)g.isBlobSchema()?m[i]=a:g.isStringSchema()?m[i]=(this.serdeContext?.utf8Encoder??z)(a):g.isStructSchema()&&(m[i]=await this.deserializer.read(g,a));else if(v){const b=e[t].headers[i]?.value;b!=null&&(g.isNumericSchema()?b&&typeof b=="object"&&"bytes"in b?m[i]=BigInt(b.toString()):m[i]=Number(b):m[i]=b)}}if(f)return{[t]:m};if(a.byteLength===0)return{[t]:{}}}return{[t]:await this.deserializer.read(o,a)}}else return{$unknown:e}}),p=u[Symbol.asyncIterator](),r=await p.next();if(r.done)return u;if(r.value?.[h]){if(!n)throw new Error("@smithy::core/protocols - initial-response event encountered in event stream but no response schema given.");for(const e in r.value)l[e]=r.value[e]}return{async*[Symbol.asyncIterator](){for(r?.value?.[h]||(yield r.value);;){const{done:e,value:t}=await p.next();if(e)break;yield t}}}}writeEventBody(s,n,l){const c=this.serializer;let y=s,S=null,d;const h=n.getSchema()[4].includes(s),u={};if(h){const e=n.getMemberSchema(s);if(e.isStructSchema()){for(const[t,a]of e.structIterator()){const{eventHeader:o,eventPayload:m}=a.getMergedTraits();if(m)S=t;else if(o){const f=l[s][t];let i="binary";a.isNumericSchema()?(-2)**31<=f&&f<=2**31-1?i="integer":i="long":a.isTimestampSchema()?i="timestamp":a.isStringSchema()?i="string":a.isBooleanSchema()&&(i="boolean"),f!=null&&(u[t]={type:i,value:f},delete l[s][t])}}if(S!==null){const t=e.getMemberSchema(S);t.isBlobSchema()?d="application/octet-stream":t.isStringSchema()&&(d="text/plain"),c.write(t,l[s][S])}else c.write(e,l[s])}else if(e.isUnitSchema())c.write(e,{});else throw new Error("@smithy/core/event-streams - non-struct member not supported in event stream union.")}else{const[e,t]=l[s];y=e,c.write(15,t)}const p=c.flush()??new Uint8Array;return{body:typeof p=="string"?(this.serdeContext?.utf8Decoder??k)(p):p,eventType:y,explicitPayloadContentType:d,additionalHeaders:u}}}export{_ as EventStreamSerde};
1
+ import{G as z,H as k}from"./index-Bf-xVuDm.js";import"./virtualExposes-DN39MDG_.js";import"./virtual_mf-REMOTE_ENTRY_ID___mfe_internal__reventless_host_shell__remoteEntry-_hash_-C8lRAcSv.js";import"./preload-helper-BlTxHScW.js";import"./_virtual_mf___mfe_internal__reventless_host_shell__loadShare__react_mf_2_dom_mf_1_client__loadShare__.mjs-BzAfciYp.js";import"./__virtual_mf___mfe_internal__reventless_host_shell__loadShare__react_mf_2_dom__loadShare__.mjs_commonjs-proxy-BUE6rcGI.js";import"./__virtual_mf___mfe_internal__reventless_host_shell__loadShare__react__loadShare__.mjs_commonjs-proxy-CfkhEoF5.js";import"./_virtual_mf___mfe_internal__reventless_host_shell__loadShare__react_mf_1_jsx_mf_2_runtime__loadShare__.mjs-hre-5-8f.js";import"./_virtual_mf___mfe_internal__reventless_host_shell__loadShare__react__loadShare__.mjs-CuPed97e.js";import"./_virtual_mf___mfe_internal__reventless_host_shell__loadShare__react_mf_2_dom__loadShare__.mjs-Bp_g55i_.js";class _{marshaller;serializer;deserializer;serdeContext;defaultContentType;constructor({marshaller:s,serializer:n,deserializer:l,serdeContext:c,defaultContentType:y}){this.marshaller=s,this.serializer=n,this.deserializer=l,this.serdeContext=c,this.defaultContentType=y}async serializeEventStream({eventStream:s,requestSchema:n,initialRequest:l}){const c=this.marshaller,y=n.getEventStreamMember(),S=n.getMemberSchema(y),d=this.serializer,h=this.defaultContentType,u=Symbol("initialRequestMarker"),p={async*[Symbol.asyncIterator](){if(l){const r={":event-type":{type:"string",value:"initial-request"},":message-type":{type:"string",value:"event"},":content-type":{type:"string",value:h}};d.write(n,l);const e=d.flush();yield{[u]:!0,headers:r,body:e}}for await(const r of s)yield r}};return c.serialize(p,r=>{if(r[u])return{headers:r.headers,body:r.body};let e="";for(const i in r)if(i!=="__type"){e=i;break}const{additionalHeaders:t,body:a,eventType:o,explicitPayloadContentType:m}=this.writeEventBody(e,S,r);return{headers:{":event-type":{type:"string",value:o},":message-type":{type:"string",value:"event"},":content-type":{type:"string",value:m??h},...t},body:a}})}async deserializeEventStream({response:s,responseSchema:n,initialResponseContainer:l}){const c=this.marshaller,y=n.getEventStreamMember(),d=n.getMemberSchema(y).getMemberSchemas(),h=Symbol("initialResponseMarker"),u=c.deserialize(s.body,async e=>{let t="";for(const o in e)if(o!=="__type"){t=o;break}const a=e[t].body;if(t==="initial-response"){const o=await this.deserializer.read(n,a);return delete o[y],{[h]:!0,...o}}else if(t in d){const o=d[t];if(o.isStructSchema()){const m={};let f=!1;for(const[i,g]of o.structIterator()){const{eventHeader:v,eventPayload:w}=g.getMergedTraits();if(f=f||!!(v||w),w)g.isBlobSchema()?m[i]=a:g.isStringSchema()?m[i]=(this.serdeContext?.utf8Encoder??z)(a):g.isStructSchema()&&(m[i]=await this.deserializer.read(g,a));else if(v){const b=e[t].headers[i]?.value;b!=null&&(g.isNumericSchema()?b&&typeof b=="object"&&"bytes"in b?m[i]=BigInt(b.toString()):m[i]=Number(b):m[i]=b)}}if(f)return{[t]:m};if(a.byteLength===0)return{[t]:{}}}return{[t]:await this.deserializer.read(o,a)}}else return{$unknown:e}}),p=u[Symbol.asyncIterator](),r=await p.next();if(r.done)return u;if(r.value?.[h]){if(!n)throw new Error("@smithy::core/protocols - initial-response event encountered in event stream but no response schema given.");for(const e in r.value)l[e]=r.value[e]}return{async*[Symbol.asyncIterator](){for(r?.value?.[h]||(yield r.value);;){const{done:e,value:t}=await p.next();if(e)break;yield t}}}}writeEventBody(s,n,l){const c=this.serializer;let y=s,S=null,d;const h=n.getSchema()[4].includes(s),u={};if(h){const e=n.getMemberSchema(s);if(e.isStructSchema()){for(const[t,a]of e.structIterator()){const{eventHeader:o,eventPayload:m}=a.getMergedTraits();if(m)S=t;else if(o){const f=l[s][t];let i="binary";a.isNumericSchema()?(-2)**31<=f&&f<=2**31-1?i="integer":i="long":a.isTimestampSchema()?i="timestamp":a.isStringSchema()?i="string":a.isBooleanSchema()&&(i="boolean"),f!=null&&(u[t]={type:i,value:f},delete l[s][t])}}if(S!==null){const t=e.getMemberSchema(S);t.isBlobSchema()?d="application/octet-stream":t.isStringSchema()&&(d="text/plain"),c.write(t,l[s][S])}else c.write(e,l[s])}else if(e.isUnitSchema())c.write(e,{});else throw new Error("@smithy/core/event-streams - non-struct member not supported in event stream union.")}else{const[e,t]=l[s];y=e,c.write(15,t)}const p=c.flush()??new Uint8Array;return{body:typeof p=="string"?(this.serdeContext?.utf8Decoder??k)(p):p,eventType:y,explicitPayloadContentType:d,additionalHeaders:u}}}export{_ as EventStreamSerde};
@@ -14,4 +14,4 @@ const __mfImport = (src) =>
14
14
  const runtime = await initHost();
15
15
  const __mfRemotePreloads = [];
16
16
  await Promise.all(__mfRemotePreloads);
17
- })().then(() => __mfImport("/assets/index-BLP8Blsh.js"));
17
+ })().then(() => __mfImport("/assets/index-Bf-xVuDm.js"));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reventlessdev/reventless-host-shell",
3
- "version": "3.0.0-alpha.73",
3
+ "version": "3.0.0-alpha.74",
4
4
  "description": "Reventless host shell SPA — loads plugin UI fragments at runtime via Module Federation",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "bin": {
@@ -28,10 +28,10 @@
28
28
  "@aws-sdk/client-cognito-identity-provider": "^3.658.0",
29
29
  "@module-federation/runtime": "^0.18.0",
30
30
  "@rescript/react": "^0.13.1",
31
- "@reventlessdev/reventless-graph": "0.1.0-alpha.30",
32
- "@reventlessdev/reventless-map": "0.1.0-alpha.30",
31
+ "@reventlessdev/reventless-graph": "0.1.0-alpha.31",
32
+ "@reventlessdev/reventless-map": "0.1.0-alpha.31",
33
33
  "@reventlessdev/reventless-routes": "3.0.0-alpha.12",
34
- "@reventlesslab/reventless-ui": "3.0.0-alpha.69",
34
+ "@reventlesslab/reventless-ui": "3.0.0-alpha.70",
35
35
  "graphql-ws": "^5.16.0",
36
36
  "jwt-decode": "^4.0.0",
37
37
  "react": "^18.3.1",
@@ -46,5 +46,5 @@
46
46
  "registry": "https://registry.npmjs.org",
47
47
  "access": "public"
48
48
  },
49
- "gitHead": "3ebbb145dbd9e9c7f074688e14e9aad444b1d5cb"
49
+ "gitHead": "7b58049c491588cb610754cabf6e341136dd93e3"
50
50
  }
package/vite.config.mjs CHANGED
@@ -1,4 +1,6 @@
1
1
  import { federation } from "@module-federation/vite"
2
+ import { existsSync, readFileSync, readdirSync, statSync } from "node:fs"
3
+ import { dirname, join, resolve } from "node:path"
2
4
 
3
5
  // The host shell ships with no build-time remotes. Plugin remotes are
4
6
  // discovered at runtime via the Platform_UIFragments GraphQL query and
@@ -51,8 +53,134 @@ const proxy = {
51
53
  },
52
54
  }
53
55
 
56
+ // The four files a running platform overlays into the shell's served assets.
57
+ // `config.json` and `ui-hints.json` exist in `public/` too and are overridden;
58
+ // the manifests exist nowhere else, so without this they simply 404.
59
+ const overlaidFile = path =>
60
+ path === "/config.json" ||
61
+ path === "/ui-hints.json" ||
62
+ /^\/component-manifest[a-zA-Z0-9._-]*\.json$/.test(path)
63
+
64
+ // A directory is the running platform's served assets only if it holds
65
+ // `config.base.json`. That file is written by exactly one thing — the local
66
+ // platform putting the shipped `config.json` aside before it overlays it — so
67
+ // its presence is the fact "a platform has served from here", not a guess. It is
68
+ // what keeps discovery off this package's own `dist/`, which carries the same
69
+ // file names and none of the platform's answers.
70
+ const servedAssets = dir => {
71
+ const dist = dir.endsWith("dist") ? dir : join(dir, "node_modules/@reventlessdev/reventless-host-shell/dist")
72
+ return existsSync(join(dist, "config.base.json")) ? dist : null
73
+ }
74
+
75
+ const subdirs = dir => {
76
+ try {
77
+ return readdirSync(dir)
78
+ .filter(n => !n.startsWith(".") && n !== "node_modules")
79
+ .map(n => join(dir, n))
80
+ .filter(p => {
81
+ try {
82
+ return statSync(p).isDirectory()
83
+ } catch {
84
+ return false
85
+ }
86
+ })
87
+ } catch {
88
+ return []
89
+ }
90
+ }
91
+
92
+ /**
93
+ * Where the running platform put the files it overlays.
94
+ *
95
+ * `REVENTLESS_PLATFORM_DIR` wins and is the only thing that always works: it
96
+ * names the directory the platform runs from, which is where `HostShellDist`
97
+ * resolves the package from on that side. Point it at a platform root (or
98
+ * straight at a dist) and the two cannot disagree.
99
+ *
100
+ * Unset, we look. Ancestors of the cwd first, then the immediate siblings of the
101
+ * checkout this file lives in — a platform in a co-located repo is the ordinary
102
+ * arrangement for anyone running the UI from source, and the `config.base.json`
103
+ * gate means a wrong candidate is skipped rather than served.
104
+ */
105
+ const findServedAssets = () => {
106
+ const declared = process.env.REVENTLESS_PLATFORM_DIR ?? process.env.REVENTLESS_SHELL_DIST
107
+ if (declared) {
108
+ const found = servedAssets(resolve(declared))
109
+ return found
110
+ ? { dist: found, from: "REVENTLESS_PLATFORM_DIR" }
111
+ : { dist: null, from: `REVENTLESS_PLATFORM_DIR (${declared}) — no config.base.json under it` }
112
+ }
113
+
114
+ const ancestors = []
115
+ for (let dir = process.cwd(); ; dir = dirname(dir)) {
116
+ ancestors.push(dir)
117
+ if (dirname(dir) === dir) break
118
+ }
119
+ const checkout = ancestors.find(d => existsSync(join(d, ".git"))) ?? process.cwd()
120
+
121
+ for (const candidate of [...ancestors, ...subdirs(dirname(checkout))]) {
122
+ const found = servedAssets(candidate)
123
+ if (found) return { dist: found, from: "discovered" }
124
+ }
125
+ return { dist: null, from: "not found" }
126
+ }
127
+
128
+ /**
129
+ * Serve the running platform's overlaid assets instead of this package's `public/`.
130
+ *
131
+ * A platform states its shell's surface by writing into the served assets of the
132
+ * `@reventlessdev/reventless-host-shell` it resolves: `manifestUrl`,
133
+ * `journeyManifestUrls` and `elevatedGroups` onto `config.json`, the baked
134
+ * manifests beside it, the deployment's own `ui-hints.json` over the one this
135
+ * package ships. Running the shell from source serves `public/` instead, so none
136
+ * of it arrives — and the shell reads a config with no `manifestUrl` as "this
137
+ * deployment discovers from the admin query alone". Every caller then needs the
138
+ * Admin group, which is precisely what acting as a role gives up: switching role
139
+ * narrows the token to that role, the admin query refuses it, and the shell
140
+ * reports that the role has no surfaces. The deployment had configured one.
141
+ *
142
+ * Re-read per request rather than cached, because both ends already move: the
143
+ * platform rewrites `config.json` on every boot, and re-serves `ui-hints.json`
144
+ * on every save so a label change restacks the menu where it stands.
145
+ */
146
+ const platformAssets = () => {
147
+ let resolved
148
+ const handler = (req, res, next) => {
149
+ resolved ??= findServedAssets()
150
+ const path = (req.url ?? "").split("?")[0]
151
+ if (!resolved.dist || !overlaidFile(path)) return next()
152
+ const file = join(resolved.dist, path)
153
+ if (!existsSync(file)) return next()
154
+ res.setHeader("Content-Type", "application/json")
155
+ res.setHeader("Cache-Control", "no-store")
156
+ res.end(readFileSync(file))
157
+ }
158
+ const announce = logger => {
159
+ resolved ??= findServedAssets()
160
+ logger.info(
161
+ resolved.dist
162
+ ? ` ➜ platform assets: ${resolved.dist} (${resolved.from})`
163
+ : ` ➜ platform assets: none (${resolved.from}) — serving public/, so config.json carries no ` +
164
+ `manifestUrl and acting as a role will find no surfaces. Set REVENTLESS_PLATFORM_DIR to the ` +
165
+ `directory your platform runs from.`,
166
+ )
167
+ }
168
+ return {
169
+ name: "reventless-platform-assets",
170
+ apply: "serve",
171
+ configureServer: server => {
172
+ server.middlewares.use(handler)
173
+ announce(server.config.logger)
174
+ },
175
+ configurePreviewServer: server => {
176
+ server.middlewares.use(handler)
177
+ announce(server.config.logger)
178
+ },
179
+ }
180
+ }
181
+
54
182
  export default {
55
- plugins: [mfPlugin],
183
+ plugins: [mfPlugin, platformAssets()],
56
184
  build: {
57
185
  target: "esnext",
58
186
  outDir: "dist",