@swarm.ing/pieui 2.0.34 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/dist/agent/index.d.ts +1 -0
  2. package/dist/agent/index.d.ts.map +1 -1
  3. package/dist/agent/index.esm.js +1 -1
  4. package/dist/agent/index.js +1 -1
  5. package/dist/cli.js +273 -43
  6. package/dist/code/args.d.ts +1 -1
  7. package/dist/code/args.d.ts.map +1 -1
  8. package/dist/code/commands/createPieApp.d.ts.map +1 -1
  9. package/dist/code/commands/registry.d.ts +8 -0
  10. package/dist/code/commands/registry.d.ts.map +1 -0
  11. package/dist/code/types.d.ts +5 -0
  12. package/dist/code/types.d.ts.map +1 -1
  13. package/dist/components/LazyBoundary/index.d.ts +43 -0
  14. package/dist/components/LazyBoundary/index.d.ts.map +1 -0
  15. package/dist/components/PieBaseRoot/index.d.ts.map +1 -1
  16. package/dist/components/PieMaxRoot/index.d.ts.map +1 -1
  17. package/dist/components/PiePreviewRoot/index.d.ts +37 -0
  18. package/dist/components/PiePreviewRoot/index.d.ts.map +1 -0
  19. package/dist/components/PieRoot/index.d.ts.map +1 -1
  20. package/dist/components/PieRoot/types/index.d.ts +19 -3
  21. package/dist/components/PieRoot/types/index.d.ts.map +1 -1
  22. package/dist/components/PieTelegramRoot/index.d.ts.map +1 -1
  23. package/dist/components/UI/index.d.ts.map +1 -1
  24. package/dist/components/UILoading/index.d.ts.map +1 -1
  25. package/dist/components/index.esm.js +1 -1
  26. package/dist/components/index.js +1 -1
  27. package/dist/index.d.ts +4 -6
  28. package/dist/index.d.ts.map +1 -1
  29. package/dist/index.esm.js +2 -2
  30. package/dist/index.js +2 -2
  31. package/dist/max/index.d.ts +12 -0
  32. package/dist/max/index.d.ts.map +1 -0
  33. package/dist/max/index.esm.js +2 -0
  34. package/dist/max/index.js +2 -0
  35. package/dist/telegram/index.d.ts +12 -0
  36. package/dist/telegram/index.d.ts.map +1 -0
  37. package/dist/telegram/index.esm.js +2 -0
  38. package/dist/telegram/index.js +2 -0
  39. package/dist/util/lazy.d.ts.map +1 -1
  40. package/dist/util/lazyError.d.ts +9 -0
  41. package/dist/util/lazyError.d.ts.map +1 -0
  42. package/dist/util/registry.d.ts +28 -0
  43. package/dist/util/registry.d.ts.map +1 -1
  44. package/package.json +26 -11
@@ -8,4 +8,5 @@
8
8
  * expose PieCard methods as OpenAI function tools.
9
9
  */
10
10
  export { getMittAgentTools, usePieMittAgentTools, type MittAgentTool, type MittAgentToolDescriptor, type MittAgentToolsOptions, } from '../util/mittAgentTools';
11
+ export { default as useOpenAIWebRTC, type OpenAIEvent, type UseOpenAIWebRTCReturn, } from '../util/useOpenAIWebRTC';
11
12
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/agent/index.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AACH,OAAO,EACH,iBAAiB,EACjB,oBAAoB,EACpB,KAAK,aAAa,EAClB,KAAK,uBAAuB,EAC5B,KAAK,qBAAqB,GAC7B,MAAM,wBAAwB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/agent/index.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AACH,OAAO,EACH,iBAAiB,EACjB,oBAAoB,EACpB,KAAK,aAAa,EAClB,KAAK,uBAAuB,EAC5B,KAAK,qBAAqB,GAC7B,MAAM,wBAAwB,CAAA;AAC/B,OAAO,EACH,OAAO,IAAI,eAAe,EAC1B,KAAK,WAAW,EAChB,KAAK,qBAAqB,GAC7B,MAAM,yBAAyB,CAAA"}
@@ -1,2 +1,2 @@
1
1
  "use client";
2
- import{tool as A}from"@openai/agents";import{useContext as P,useMemo as I}from"react";import S from"mitt";import{createContext as O,useCallback as w,useContext as E}from"react";var Z=null;function $(){if(!Z)Z=S();return Z}var R=O(null);var q=R;var z=/^pie(.+?)_(.+)$/;function D(X=$(),Q={}){let G=[],H=new Set;for(let j of X.all.keys()){if(typeof j!=="string")continue;let W=j.match(z);if(!W)continue;let[,J,L]=W,B={methodName:J,cardName:L,eventName:j};if(Q.filter&&!Q.filter(B))continue;let Y=Q.nameFor?.(B)??`${L}_${J}`;if(H.has(Y))continue;H.add(Y);let U=Q.describe?.(B)??`Invokes the "${J}" method on the PieCard "${L}" by emitting the in-process mitt event "${j}". The optional "payload" argument is forwarded verbatim to the card's handler.`;G.push(A({name:Y,description:U,strict:!1,parameters:{type:"object",properties:{payload:{description:"Arbitrary JSON payload forwarded to the PieCard method handler. Omit for fire-and-forget calls."}},required:[],additionalProperties:!0},execute:async(F)=>{let V=F?.payload;return X.emit(j,V),`Emitted "${j}"`}}))}return G}function _(X={}){let G=P(q)??$(),H=[];for(let B of G.all.keys())if(typeof B==="string"&&z.test(B))H.push(B);H.sort();let j=H.join("|"),{filter:W,describe:J,nameFor:L}=X;return I(()=>D(G,{filter:W,describe:J,nameFor:L}),[G,j,W,J,L])}export{_ as usePieMittAgentTools,D as getMittAgentTools};
2
+ import{tool as x}from"@openai/agents";import{useContext as b,useMemo as k}from"react";import M from"mitt";import{createContext as w,useCallback as c,useContext as d}from"react";var P=null;function F(){if(!P)P=M();return P}var T=w(null);var O=T;var I=/^pie(.+?)_(.+)$/;function A(G=F(),H={}){let Z=[],L=new Set;for(let J of G.all.keys()){if(typeof J!=="string")continue;let Q=J.match(I);if(!Q)continue;let[,X,q]=Q,$={methodName:X,cardName:q,eventName:J};if(H.filter&&!H.filter($))continue;let W=H.nameFor?.($)??`${q}_${X}`;if(L.has(W))continue;L.add(W);let D=H.describe?.($)??`Invokes the "${X}" method on the PieCard "${q}" by emitting the in-process mitt event "${J}". The optional "payload" argument is forwarded verbatim to the card's handler.`;Z.push(x({name:W,description:D,strict:!1,parameters:{type:"object",properties:{payload:{description:"Arbitrary JSON payload forwarded to the PieCard method handler. Omit for fire-and-forget calls."}},required:[],additionalProperties:!0},execute:async(j)=>{let Y=j?.payload;return G.emit(J,Y),`Emitted "${J}"`}}))}return Z}function N(G={}){let Z=b(O)??F(),L=[];for(let $ of Z.all.keys())if(typeof $==="string"&&I.test($))L.push($);L.sort();let J=L.join("|"),{filter:Q,describe:X,nameFor:q}=G;return k(()=>A(Z,{filter:Q,describe:X,nameFor:q}),[Z,J,Q,X,q])}import{useCallback as V,useEffect as y,useRef as _,useState as f}from"react";function v(){let G=new AudioContext,H=G.createOscillator(),Z=H.connect(G.createMediaStreamDestination());H.start();let L=Z.stream.getAudioTracks()[0];return L.enabled=!1,L}function R(G=null,H){let[Z,L]=f(!1),J=_(null),Q=_(null),X=_(null),q=V(async(j,Y=!0)=>{if(J.current)$();let B=new RTCPeerConnection;if(B.onconnectionstatechange=()=>{if(B.connectionState==="connected")L(!0);else if(["disconnected","failed","closed"].includes(B.connectionState))L(!1)},B.ontrack=(z)=>{if(G)G.srcObject=z.streams[0]},Y){let z=await navigator.mediaDevices.getUserMedia({audio:!0});B.addTrack(z.getTracks()[0],z)}else{let z=v();B.addTrack(z)}let U=B.createDataChannel("oai-events");Q.current=U,X.current=new Promise((z)=>{U.addEventListener("open",()=>{z()})});let K=await B.createOffer();await B.setLocalDescription(K);let S=await(await fetch(`${"https://api.openai.com/v1/realtime/calls"}?model=${"gpt-realtime"}`,{method:"POST",body:K.sdp,headers:{Authorization:`Bearer ${j}`,"Content-Type":"application/sdp"}})).text();await B.setRemoteDescription({type:"answer",sdp:S}),J.current=B,await X.current},[G]),$=V(()=>{let j=Q.current;if(j)j.close();J.current?.getSenders()?.forEach((Y)=>Y.track?.stop()),J.current?.close(),L(!1),J.current=null,Q.current=null,X.current=null},[G]),W=V((j)=>{let Y=Q.current;if(!Y){console.error("Data channel is not ready",j);return}let B=new Date().toLocaleTimeString();if(j.event_id=j.event_id||crypto.randomUUID(),Y.send(JSON.stringify(j)),!j.timestamp)j.timestamp=B;H?.(j)},[H,G]),D=V((j)=>{if(!Q.current){console.error("Data channel is not ready");return}let B=()=>{W({type:"conversation.item.create",item:{type:"message",role:"user",content:[{type:"input_text",text:j}]}}),W({type:"response.create"})};if(X.current)X.current.then(B);else B()},[H,G]);return y(()=>{let j=Q.current;if(!j)return;let Y=(B)=>{let U=JSON.parse(B.data);if(!U.timestamp)U.timestamp=new Date().toLocaleTimeString();H?.(U)};return j.addEventListener("message",Y),()=>{j.removeEventListener("message",Y)}},[H,G]),{isSessionActive:Z,startSession:q,stopSession:$,sendTextMessage:D}}export{N as usePieMittAgentTools,R as useOpenAIWebRTC,A as getMittAgentTools};
@@ -1,2 +1,2 @@
1
1
  "use client";
2
- var M=Object.create;var{getPrototypeOf:w,defineProperty:Y,getOwnPropertyNames:V,getOwnPropertyDescriptor:E}=Object,S=Object.prototype.hasOwnProperty;var f=(j,B,G)=>{G=j!=null?M(w(j)):{};let H=B||!j||!j.__esModule?Y(G,"default",{value:j,enumerable:!0}):G;for(let J of V(j))if(!S.call(H,J))Y(H,J,{get:()=>j[J],enumerable:!0});return H},F=new WeakMap,x=(j)=>{var B=F.get(j),G;if(B)return B;if(B=Y({},"__esModule",{value:!0}),j&&typeof j==="object"||typeof j==="function")V(j).map((H)=>!S.call(B,H)&&Y(B,H,{get:()=>j[H],enumerable:!(G=E(j,H))||G.enumerable}));return F.set(j,B),B};var T=(j,B)=>{for(var G in B)Y(j,G,{get:B[G],enumerable:!0,configurable:!0,set:(H)=>B[G]=()=>H})};var C={};T(C,{usePieMittAgentTools:()=>I,getMittAgentTools:()=>U});module.exports=x(C);var A=require("@openai/agents"),$=require("react");var O=f(require("mitt")),Z=require("react"),z=null;function D(){if(!z)z=O.default();return z}var b=Z.createContext(null);var R=b;var P=/^pie(.+?)_(.+)$/;function U(j=D(),B={}){let G=[],H=new Set;for(let J of j.all.keys()){if(typeof J!=="string")continue;let X=J.match(P);if(!X)continue;let[,Q,W]=X,L={methodName:Q,cardName:W,eventName:J};if(B.filter&&!B.filter(L))continue;let q=B.nameFor?.(L)??`${W}_${Q}`;if(H.has(q))continue;H.add(q);let _=B.describe?.(L)??`Invokes the "${Q}" method on the PieCard "${W}" by emitting the in-process mitt event "${J}". The optional "payload" argument is forwarded verbatim to the card's handler.`;G.push(A.tool({name:q,description:_,strict:!1,parameters:{type:"object",properties:{payload:{description:"Arbitrary JSON payload forwarded to the PieCard method handler. Omit for fire-and-forget calls."}},required:[],additionalProperties:!0},execute:async(K)=>{let k=K?.payload;return j.emit(J,k),`Emitted "${J}"`}}))}return G}function I(j={}){let G=$.useContext(R)??D(),H=[];for(let L of G.all.keys())if(typeof L==="string"&&P.test(L))H.push(L);H.sort();let J=H.join("|"),{filter:X,describe:Q,nameFor:W}=j;return $.useMemo(()=>U(G,{filter:X,describe:Q,nameFor:W}),[G,J,X,Q,W])}
2
+ var f=Object.create;var{getPrototypeOf:v,defineProperty:D,getOwnPropertyNames:M,getOwnPropertyDescriptor:C}=Object,w=Object.prototype.hasOwnProperty;var E=(j,B,H)=>{H=j!=null?f(v(j)):{};let G=B||!j||!j.__esModule?D(H,"default",{value:j,enumerable:!0}):H;for(let L of M(j))if(!w.call(G,L))D(G,L,{get:()=>j[L],enumerable:!0});return G},S=new WeakMap,g=(j)=>{var B=S.get(j),H;if(B)return B;if(B=D({},"__esModule",{value:!0}),j&&typeof j==="object"||typeof j==="function")M(j).map((G)=>!w.call(B,G)&&D(B,G,{get:()=>j[G],enumerable:!(H=C(j,G))||H.enumerable}));return S.set(j,B),B};var u=(j,B)=>{for(var H in B)D(j,H,{get:B[H],enumerable:!0,configurable:!0,set:(G)=>B[H]=()=>G})};var c={};u(c,{usePieMittAgentTools:()=>N,useOpenAIWebRTC:()=>A,getMittAgentTools:()=>I});module.exports=g(c);var b=require("@openai/agents"),F=require("react");var T=E(require("mitt")),P=require("react"),K=null;function O(){if(!K)K=T.default();return K}var h=P.createContext(null);var x=h;var k=/^pie(.+?)_(.+)$/;function I(j=O(),B={}){let H=[],G=new Set;for(let L of j.all.keys()){if(typeof L!=="string")continue;let Y=L.match(k);if(!Y)continue;let[,Z,z]=Y,q={methodName:Z,cardName:z,eventName:L};if(B.filter&&!B.filter(q))continue;let V=B.nameFor?.(q)??`${z}_${Z}`;if(G.has(V))continue;G.add(V);let _=B.describe?.(q)??`Invokes the "${Z}" method on the PieCard "${z}" by emitting the in-process mitt event "${L}". The optional "payload" argument is forwarded verbatim to the card's handler.`;H.push(b.tool({name:V,description:_,strict:!1,parameters:{type:"object",properties:{payload:{description:"Arbitrary JSON payload forwarded to the PieCard method handler. Omit for fire-and-forget calls."}},required:[],additionalProperties:!0},execute:async(J)=>{let $=J?.payload;return j.emit(L,$),`Emitted "${L}"`}}))}return H}function N(j={}){let H=F.useContext(x)??O(),G=[];for(let q of H.all.keys())if(typeof q==="string"&&k.test(q))G.push(q);G.sort();let L=G.join("|"),{filter:Y,describe:Z,nameFor:z}=j;return F.useMemo(()=>I(H,{filter:Y,describe:Z,nameFor:z}),[H,L,Y,Z,z])}var X=require("react");function p(){let j=new AudioContext,B=j.createOscillator(),H=B.connect(j.createMediaStreamDestination());B.start();let G=H.stream.getAudioTracks()[0];return G.enabled=!1,G}function A(j=null,B){let[H,G]=X.useState(!1),L=X.useRef(null),Y=X.useRef(null),Z=X.useRef(null),z=X.useCallback(async(J,$=!0)=>{if(L.current)q();let Q=new RTCPeerConnection;if(Q.onconnectionstatechange=()=>{if(Q.connectionState==="connected")G(!0);else if(["disconnected","failed","closed"].includes(Q.connectionState))G(!1)},Q.ontrack=(U)=>{if(j)j.srcObject=U.streams[0]},$){let U=await navigator.mediaDevices.getUserMedia({audio:!0});Q.addTrack(U.getTracks()[0],U)}else{let U=p();Q.addTrack(U)}let W=Q.createDataChannel("oai-events");Y.current=W,Z.current=new Promise((U)=>{W.addEventListener("open",()=>{U()})});let R=await Q.createOffer();await Q.setLocalDescription(R);let y=await(await fetch(`${"https://api.openai.com/v1/realtime/calls"}?model=${"gpt-realtime"}`,{method:"POST",body:R.sdp,headers:{Authorization:`Bearer ${J}`,"Content-Type":"application/sdp"}})).text();await Q.setRemoteDescription({type:"answer",sdp:y}),L.current=Q,await Z.current},[j]),q=X.useCallback(()=>{let J=Y.current;if(J)J.close();L.current?.getSenders()?.forEach(($)=>$.track?.stop()),L.current?.close(),G(!1),L.current=null,Y.current=null,Z.current=null},[j]),V=X.useCallback((J)=>{let $=Y.current;if(!$){console.error("Data channel is not ready",J);return}let Q=new Date().toLocaleTimeString();if(J.event_id=J.event_id||crypto.randomUUID(),$.send(JSON.stringify(J)),!J.timestamp)J.timestamp=Q;B?.(J)},[B,j]),_=X.useCallback((J)=>{if(!Y.current){console.error("Data channel is not ready");return}let Q=()=>{V({type:"conversation.item.create",item:{type:"message",role:"user",content:[{type:"input_text",text:J}]}}),V({type:"response.create"})};if(Z.current)Z.current.then(Q);else Q()},[B,j]);return X.useEffect(()=>{let J=Y.current;if(!J)return;let $=(Q)=>{let W=JSON.parse(Q.data);if(!W.timestamp)W.timestamp=new Date().toLocaleTimeString();B?.(W)};return J.addEventListener("message",$),()=>{J.removeEventListener("message",$)}},[B,j]),{isSessionActive:H,startSession:z,stopSession:q,sendTextMessage:_}}
package/dist/cli.js CHANGED
@@ -188176,7 +188176,7 @@ var require_typescript_json_schema = __commonJS((exports2) => {
188176
188176
  });
188177
188177
 
188178
188178
  // src/cli.ts
188179
- var import_node_path23 = __toESM(require("node:path"));
188179
+ var import_node_path24 = __toESM(require("node:path"));
188180
188180
 
188181
188181
  // src/code/args.ts
188182
188182
  var VALID_CARD_ACTIONS = [
@@ -188434,6 +188434,29 @@ var parseArgs = (argv) => {
188434
188434
  result.pageAjaxHandler = argv[4];
188435
188435
  }
188436
188436
  }
188437
+ if (command === "registry" && argv[1]) {
188438
+ const action = argv[1];
188439
+ if (action === "dev" || action === "build") {
188440
+ result.registryAction = action;
188441
+ const tail = argv.slice(2);
188442
+ for (let i = 0;i < tail.length; i++) {
188443
+ const tok = tail[i];
188444
+ if (tok === "--port" && tail[i + 1]) {
188445
+ result.registryPort = parseIntFlag("--port", tail[++i]);
188446
+ } else if (tok.startsWith("--port=")) {
188447
+ result.registryPort = parseIntFlag("--port", tok.slice("--port=".length));
188448
+ } else if (tok === "--api-server" && tail[i + 1]) {
188449
+ result.registryApiServer = tail[++i];
188450
+ } else if (tok.startsWith("--api-server=")) {
188451
+ result.registryApiServer = tok.slice("--api-server=".length);
188452
+ } else if (tok === "--out" && tail[i + 1]) {
188453
+ result.registryOut = tail[++i];
188454
+ } else if (tok.startsWith("--out=")) {
188455
+ result.registryOut = tok.slice("--out=".length);
188456
+ }
188457
+ }
188458
+ }
188459
+ }
188437
188460
  return result;
188438
188461
  };
188439
188462
  var detectHelpScope = (argv) => {
@@ -188448,6 +188471,8 @@ var detectHelpScope = (argv) => {
188448
188471
  return "card";
188449
188472
  if (c0 === "page")
188450
188473
  return "page";
188474
+ if (c0 === "registry")
188475
+ return "registry";
188451
188476
  if (c0 === "init")
188452
188477
  return "init";
188453
188478
  if (c0 === "postbuild")
@@ -188500,6 +188525,10 @@ var ALL_LINES = [
188500
188525
  " page view <path> Print app/<path>/page.tsx source",
188501
188526
  " page ajax <path> <add|remove> <handler> Add or remove an AJAX handler in app/<path>/page.tsx",
188502
188527
  "",
188528
+ "Registry preview harness (standalone PiePreviewRoot, no app layout):",
188529
+ " registry dev [--port N] [--api-server URL] Run the preview harness dev server (used by `pie card show`)",
188530
+ " registry build [--out DIR] Static-export the harness (served by `pie` with disable_serving=False)",
188531
+ "",
188503
188532
  "Component types for `card add`:",
188504
188533
  " simple Simple component (only data prop)",
188505
188534
  " complex Complex component (data + children props)",
@@ -197348,6 +197377,189 @@ var pageAjaxCommand = (pageName, action, handlerName) => {
197348
197377
  }
197349
197378
  };
197350
197379
 
197380
+ // src/code/commands/registry.ts
197381
+ var import_node_fs19 = __toESM(require("node:fs"));
197382
+ var import_node_path20 = __toESM(require("node:path"));
197383
+ var import_node_child_process6 = require("node:child_process");
197384
+ var REGISTRY_DIR = ".pie/registry";
197385
+ var OUT_DIRNAME = "out";
197386
+ var writeIfChanged = (filePath, contents) => {
197387
+ if (import_node_fs19.default.existsSync(filePath) && import_node_fs19.default.readFileSync(filePath, "utf8") === contents) {
197388
+ return;
197389
+ }
197390
+ import_node_fs19.default.mkdirSync(import_node_path20.default.dirname(filePath), { recursive: true });
197391
+ import_node_fs19.default.writeFileSync(filePath, contents, "utf8");
197392
+ };
197393
+ var scaffoldHarness = (frontendRoot, registryName) => {
197394
+ const dir = import_node_path20.default.join(frontendRoot, REGISTRY_DIR);
197395
+ writeIfChanged(import_node_path20.default.join(dir, "package.json"), JSON.stringify({ name: "pie-registry-preview", version: "0.0.0", private: true }, null, 2) + `
197396
+ `);
197397
+ writeIfChanged(import_node_path20.default.join(dir, "next.config.mjs"), `import path from 'node:path'
197398
+
197399
+ // Next runs with cwd = this harness dir; the frontend project is two levels up.
197400
+ const harnessRoot = process.cwd()
197401
+ const frontendRoot = path.resolve(harnessRoot, '..', '..')
197402
+
197403
+ /** @type {import('next').NextConfig} */
197404
+ export default {
197405
+ output: 'export',
197406
+ reactStrictMode: true,
197407
+ // Next 16 blocks dev requests from non-localhost origins; allow loopback so
197408
+ // the HMR socket / lazy chunk loading work when opened via 127.0.0.1.
197409
+ allowedDevOrigins: ['127.0.0.1', 'localhost'],
197410
+ images: { unoptimized: true },
197411
+ typescript: { ignoreBuildErrors: true },
197412
+ transpilePackages: ['@swarm.ing/pieui'],
197413
+ // The workspace root must be the frontend project: that's where node_modules
197414
+ // (incl. \`next\`) lives and where the card registry + cards are imported from
197415
+ // (outside this harness dir). The app dir stays this harness (cwd).
197416
+ outputFileTracingRoot: frontendRoot,
197417
+ env: {
197418
+ PIE_API_SERVER: process.env.PIE_API_SERVER ?? '',
197419
+ NEXT_PUBLIC_PIE_API_SERVER: process.env.NEXT_PUBLIC_PIE_API_SERVER ?? '',
197420
+ },
197421
+ turbopack: { root: frontendRoot, resolveAlias: { '@': frontendRoot } },
197422
+ webpack: (config) => {
197423
+ config.resolve = config.resolve || {}
197424
+ config.resolve.alias = { ...(config.resolve.alias || {}), '@': frontendRoot }
197425
+ return config
197426
+ },
197427
+ }
197428
+ `);
197429
+ writeIfChanged(import_node_path20.default.join(dir, "tsconfig.json"), JSON.stringify({
197430
+ compilerOptions: {
197431
+ target: "ES2017",
197432
+ lib: ["dom", "dom.iterable", "esnext"],
197433
+ allowJs: true,
197434
+ skipLibCheck: true,
197435
+ strict: false,
197436
+ noEmit: true,
197437
+ esModuleInterop: true,
197438
+ module: "esnext",
197439
+ moduleResolution: "bundler",
197440
+ resolveJsonModule: true,
197441
+ isolatedModules: true,
197442
+ jsx: "preserve",
197443
+ incremental: true,
197444
+ baseUrl: "../..",
197445
+ paths: { "@/*": ["./*"] },
197446
+ plugins: [{ name: "next" }]
197447
+ },
197448
+ include: [
197449
+ "next-env.d.ts",
197450
+ "**/*.ts",
197451
+ "**/*.tsx",
197452
+ ".next/types/**/*.ts"
197453
+ ],
197454
+ exclude: ["node_modules"]
197455
+ }, null, 2) + `
197456
+ `);
197457
+ writeIfChanged(import_node_path20.default.join(dir, "app", "layout.tsx"), `import '@/app/globals.css'
197458
+
197459
+ export const metadata = { title: 'Pie Registry Preview' }
197460
+
197461
+ export default function RootLayout({
197462
+ children,
197463
+ }: {
197464
+ children: React.ReactNode
197465
+ }) {
197466
+ return (
197467
+ <html lang="en">
197468
+ <body>{children}</body>
197469
+ </html>
197470
+ )
197471
+ }
197472
+ `);
197473
+ writeIfChanged(import_node_path20.default.join(dir, "app", "page.tsx"), `'use client'
197474
+
197475
+ import dynamic from 'next/dynamic'
197476
+
197477
+ const PreviewClient = dynamic(
197478
+ () =>
197479
+ import('./preview-client').catch((e) => ({
197480
+ default: () => (
197481
+ <pre style={{ color: 'red', padding: 16, whiteSpace: 'pre-wrap' }}>
197482
+ {'[pie] preview harness failed to load:\\n' + String(e && e.stack ? e.stack : e)}
197483
+ </pre>
197484
+ ),
197485
+ })),
197486
+ { ssr: false, loading: () => <div style={{ padding: 16 }}>harness loading…</div> }
197487
+ )
197488
+
197489
+ export default function Page() {
197490
+ return <PreviewClient />
197491
+ }
197492
+ `);
197493
+ writeIfChanged(import_node_path20.default.join(dir, "app", "preview-client.tsx"), `'use client'
197494
+
197495
+ import '@/${registryName}/registry'
197496
+ import { PiePreviewRoot } from '@swarm.ing/pieui'
197497
+
197498
+ export default function PreviewClient() {
197499
+ // Dev: NEXT_PUBLIC_PIE_API_SERVER points at the ephemeral backend (Next
197500
+ // statically inlines NEXT_PUBLIC_* into the client bundle). Static build:
197501
+ // unset → falls back to same-origin '/' (pie serves both the SPA and API).
197502
+ const apiServer = process.env.NEXT_PUBLIC_PIE_API_SERVER || '/'
197503
+ return <PiePreviewRoot apiServer={apiServer} pathname="/" />
197504
+ }
197505
+ `);
197506
+ writeIfChanged(import_node_path20.default.join(dir, ".gitignore"), `*
197507
+ `);
197508
+ return dir;
197509
+ };
197510
+ var resolveNextBin = (frontendRoot) => {
197511
+ const bin = import_node_path20.default.join(frontendRoot, "node_modules", ".bin", "next");
197512
+ if (!import_node_fs19.default.existsSync(bin)) {
197513
+ throw new Error(`Next.js binary not found at ${bin}. Install dependencies in the ` + `frontend project first (the registry harness reuses them).`);
197514
+ }
197515
+ return bin;
197516
+ };
197517
+ var registryCommand = (action, opts = {}) => {
197518
+ const frontendRoot = process.cwd();
197519
+ const settings = loadSettings(frontendRoot);
197520
+ const registryName = import_node_path20.default.basename(settings.componentsDir);
197521
+ const dir = scaffoldHarness(frontendRoot, registryName);
197522
+ const nextBin = resolveNextBin(frontendRoot);
197523
+ const env = { ...process.env };
197524
+ if (opts.apiServer) {
197525
+ env.PIE_API_SERVER = opts.apiServer;
197526
+ env.NEXT_PUBLIC_PIE_API_SERVER = opts.apiServer;
197527
+ }
197528
+ if (action === "dev") {
197529
+ const port = opts.port ?? 3210;
197530
+ console.log(`[pieui] registry dev → http://localhost:${port}`);
197531
+ console.log(`[pieui] harness: ${dir}`);
197532
+ console.log(`[pieui] PIE_API_SERVER=${env.PIE_API_SERVER ?? "(unset → /)"}`);
197533
+ const result2 = import_node_child_process6.spawnSync(nextBin, ["dev", "-p", String(port)], {
197534
+ cwd: dir,
197535
+ stdio: "inherit",
197536
+ env
197537
+ });
197538
+ if (result2.error)
197539
+ throw result2.error;
197540
+ if (typeof result2.status === "number" && result2.status !== 0) {
197541
+ process.exitCode = result2.status;
197542
+ }
197543
+ return;
197544
+ }
197545
+ delete env.PIE_API_SERVER;
197546
+ delete env.NEXT_PUBLIC_PIE_API_SERVER;
197547
+ console.log(`[pieui] registry build (static export) → ${import_node_path20.default.join(dir, OUT_DIRNAME)}`);
197548
+ const result = import_node_child_process6.spawnSync(nextBin, ["build"], {
197549
+ cwd: dir,
197550
+ stdio: "inherit",
197551
+ env
197552
+ });
197553
+ if (result.error)
197554
+ throw result.error;
197555
+ if (typeof result.status === "number" && result.status !== 0) {
197556
+ process.exitCode = result.status;
197557
+ return;
197558
+ }
197559
+ const outDir = opts.out ? import_node_path20.default.resolve(frontendRoot, opts.out) : import_node_path20.default.join(dir, OUT_DIRNAME);
197560
+ console.log(`[pieui] registry build complete: ${outDir}`);
197561
+ };
197562
+
197351
197563
  // src/code/commands/create.ts
197352
197564
  var import_fs9 = __toESM(require("fs"));
197353
197565
  var import_path11 = __toESM(require("path"));
@@ -197467,7 +197679,8 @@ var DEFAULT_SHARED_SIMPLE_TSX = `"use client";
197467
197679
 
197468
197680
  import { useEffect, useState } from "react";
197469
197681
  import { useRouter } from "next/navigation";
197470
- import { PieTelegramRoot, PieQueryOptions } from "@swarm.ing/pieui";
197682
+ import { PieQueryOptions } from "@swarm.ing/pieui";
197683
+ import { PieTelegramRoot } from "@swarm.ing/pieui/telegram";
197471
197684
 
197472
197685
  import { usePathname, useSearchParams } from "next/navigation";
197473
197686
  import LoadingScreen from "@/components/LoadingScreen";
@@ -197705,49 +197918,49 @@ var createPieAppCommand = (appName) => {
197705
197918
  };
197706
197919
 
197707
197920
  // src/code/commands/login.ts
197708
- var import_node_child_process6 = require("node:child_process");
197921
+ var import_node_child_process7 = require("node:child_process");
197709
197922
  var import_node_crypto = require("node:crypto");
197710
- var import_node_fs20 = __toESM(require("node:fs"));
197711
- var import_node_path21 = __toESM(require("node:path"));
197923
+ var import_node_fs21 = __toESM(require("node:fs"));
197924
+ var import_node_path22 = __toESM(require("node:path"));
197712
197925
 
197713
197926
  // src/code/services/projectLinks.ts
197714
- var import_node_fs19 = __toESM(require("node:fs"));
197715
- var import_node_path20 = __toESM(require("node:path"));
197927
+ var import_node_fs20 = __toESM(require("node:fs"));
197928
+ var import_node_path21 = __toESM(require("node:path"));
197716
197929
  var readline3 = __toESM(require("node:readline/promises"));
197717
197930
  var PIE_CONFIG_DIR3 = ".pie";
197718
197931
  var PIE_CONFIG_FILE3 = "config.json";
197719
- var configPathFor = (cwd) => import_node_path20.default.join(cwd, PIE_CONFIG_DIR3, PIE_CONFIG_FILE3);
197932
+ var configPathFor = (cwd) => import_node_path21.default.join(cwd, PIE_CONFIG_DIR3, PIE_CONFIG_FILE3);
197720
197933
  var readConfig2 = (cwd) => {
197721
197934
  const p = configPathFor(cwd);
197722
- if (!import_node_fs19.default.existsSync(p))
197935
+ if (!import_node_fs20.default.existsSync(p))
197723
197936
  return {};
197724
197937
  try {
197725
- const parsed = JSON.parse(import_node_fs19.default.readFileSync(p, "utf8"));
197938
+ const parsed = JSON.parse(import_node_fs20.default.readFileSync(p, "utf8"));
197726
197939
  return typeof parsed === "object" && parsed !== null && !Array.isArray(parsed) ? parsed : {};
197727
197940
  } catch {
197728
197941
  return {};
197729
197942
  }
197730
197943
  };
197731
197944
  var writeConfig2 = (cwd, config) => {
197732
- const dir = import_node_path20.default.join(cwd, PIE_CONFIG_DIR3);
197733
- import_node_fs19.default.mkdirSync(dir, { recursive: true });
197734
- import_node_fs19.default.writeFileSync(configPathFor(cwd), JSON.stringify(config, null, 2) + `
197945
+ const dir = import_node_path21.default.join(cwd, PIE_CONFIG_DIR3);
197946
+ import_node_fs20.default.mkdirSync(dir, { recursive: true });
197947
+ import_node_fs20.default.writeFileSync(configPathFor(cwd), JSON.stringify(config, null, 2) + `
197735
197948
  `, "utf8");
197736
197949
  };
197737
197950
  var walkUpForPyproject2 = (start) => {
197738
- let dir = import_node_path20.default.resolve(start);
197739
- while (dir !== import_node_path20.default.dirname(dir)) {
197740
- if (import_node_fs19.default.existsSync(import_node_path20.default.join(dir, "pyproject.toml")))
197951
+ let dir = import_node_path21.default.resolve(start);
197952
+ while (dir !== import_node_path21.default.dirname(dir)) {
197953
+ if (import_node_fs20.default.existsSync(import_node_path21.default.join(dir, "pyproject.toml")))
197741
197954
  return dir;
197742
- dir = import_node_path20.default.dirname(dir);
197955
+ dir = import_node_path21.default.dirname(dir);
197743
197956
  }
197744
197957
  return null;
197745
197958
  };
197746
197959
  var ensureBackendDir2 = async (cwd) => {
197747
197960
  const config = readConfig2(cwd);
197748
197961
  if (config.backendProjectDir) {
197749
- const dir = import_node_path20.default.resolve(cwd, config.backendProjectDir);
197750
- if (import_node_fs19.default.existsSync(dir) && import_node_fs19.default.statSync(dir).isDirectory())
197962
+ const dir = import_node_path21.default.resolve(cwd, config.backendProjectDir);
197963
+ if (import_node_fs20.default.existsSync(dir) && import_node_fs20.default.statSync(dir).isDirectory())
197751
197964
  return dir;
197752
197965
  console.error(`[pieui] Configured backendProjectDir not found: ${dir}`);
197753
197966
  }
@@ -197772,9 +197985,9 @@ var ensureBackendDir2 = async (cwd) => {
197772
197985
  const raw = (await rl.question("[pieui] Path to backend (pie) project: ")).trim();
197773
197986
  if (!raw)
197774
197987
  return null;
197775
- const expanded = raw.startsWith("~") ? import_node_path20.default.join(process.env.HOME || "", raw.slice(1).replace(/^[\\/]/, "")) : raw;
197776
- const absolute = import_node_path20.default.resolve(expanded);
197777
- if (!import_node_fs19.default.existsSync(absolute) || !import_node_fs19.default.statSync(absolute).isDirectory()) {
197988
+ const expanded = raw.startsWith("~") ? import_node_path21.default.join(process.env.HOME || "", raw.slice(1).replace(/^[\\/]/, "")) : raw;
197989
+ const absolute = import_node_path21.default.resolve(expanded);
197990
+ if (!import_node_fs20.default.existsSync(absolute) || !import_node_fs20.default.statSync(absolute).isDirectory()) {
197778
197991
  console.error(`[pieui] Not a directory: ${absolute}`);
197779
197992
  return null;
197780
197993
  }
@@ -197808,11 +198021,11 @@ var generateCode = (length = CODE_LENGTH) => {
197808
198021
  var tryOpenBrowser = (url) => {
197809
198022
  try {
197810
198023
  if (process.platform === "win32") {
197811
- import_node_child_process6.execFile("cmd", ["/c", "start", "", url], () => {});
198024
+ import_node_child_process7.execFile("cmd", ["/c", "start", "", url], () => {});
197812
198025
  } else if (process.platform === "darwin") {
197813
- import_node_child_process6.execFile("open", [url], () => {});
198026
+ import_node_child_process7.execFile("open", [url], () => {});
197814
198027
  } else {
197815
- import_node_child_process6.execFile("xdg-open", [url], () => {});
198028
+ import_node_child_process7.execFile("xdg-open", [url], () => {});
197816
198029
  }
197817
198030
  } catch {}
197818
198031
  };
@@ -197843,8 +198056,8 @@ var appendPieCredentialsToEnv = (cwd, config) => {
197843
198056
  if (Object.keys(entries).length === 0) {
197844
198057
  return;
197845
198058
  }
197846
- const envPath = import_node_path21.default.join(cwd, ".env");
197847
- let content = import_node_fs20.default.existsSync(envPath) ? import_node_fs20.default.readFileSync(envPath, "utf8") : "";
198059
+ const envPath = import_node_path22.default.join(cwd, ".env");
198060
+ let content = import_node_fs21.default.existsSync(envPath) ? import_node_fs21.default.readFileSync(envPath, "utf8") : "";
197848
198061
  if (content.length > 0 && !content.endsWith(`
197849
198062
  `)) {
197850
198063
  content += `
@@ -197854,7 +198067,7 @@ var appendPieCredentialsToEnv = (cwd, config) => {
197854
198067
  content += `${additions.join(`
197855
198068
  `)}
197856
198069
  `;
197857
- import_node_fs20.default.writeFileSync(envPath, content, "utf8");
198070
+ import_node_fs21.default.writeFileSync(envPath, content, "utf8");
197858
198071
  console.log(`[pie] Appended credentials to ${envPath}`);
197859
198072
  };
197860
198073
  async function loginCommand(options = {}) {
@@ -197875,8 +198088,8 @@ async function loginCommand(options = {}) {
197875
198088
  try {
197876
198089
  openBrowser(connectUrl);
197877
198090
  } catch {}
197878
- const pieDir = import_node_path21.default.join(cwd, ".pie");
197879
- const configPath = import_node_path21.default.join(pieDir, "config.json");
198091
+ const pieDir = import_node_path22.default.join(cwd, ".pie");
198092
+ const configPath = import_node_path22.default.join(pieDir, "config.json");
197880
198093
  const url = `${credentialsApi}?${new URLSearchParams({ code }).toString()}`;
197881
198094
  let first = true;
197882
198095
  while (true) {
@@ -197910,7 +198123,7 @@ async function loginCommand(options = {}) {
197910
198123
  throw new Error("Login succeeded but response had no 'config' field");
197911
198124
  }
197912
198125
  const credBlob = typeof record.config === "object" && record.config !== null && !Array.isArray(record.config) ? record.config : {};
197913
- import_node_fs20.default.mkdirSync(pieDir, { recursive: true });
198126
+ import_node_fs21.default.mkdirSync(pieDir, { recursive: true });
197914
198127
  mergeConfig(cwd, credBlob);
197915
198128
  console.log(`[pie] Saved credentials to ${configPath}`);
197916
198129
  appendPieCredentialsToEnv(cwd, record.config);
@@ -197925,9 +198138,9 @@ async function loginCommand(options = {}) {
197925
198138
  }
197926
198139
 
197927
198140
  // src/code/commands/selfUpgrade.ts
197928
- var import_node_child_process7 = require("node:child_process");
197929
- var import_node_fs21 = __toESM(require("node:fs"));
197930
- var import_node_path22 = __toESM(require("node:path"));
198141
+ var import_node_child_process8 = require("node:child_process");
198142
+ var import_node_fs22 = __toESM(require("node:fs"));
198143
+ var import_node_path23 = __toESM(require("node:path"));
197931
198144
  var __dirname = "/home/runner/work/pieui/pieui/src/code/commands";
197932
198145
  var PACKAGE_NAME = "@swarm.ing/pieui";
197933
198146
  var INSTALL_ARGS = {
@@ -197938,7 +198151,7 @@ var INSTALL_ARGS = {
197938
198151
  };
197939
198152
  var isPackageManager = (value2) => value2 === "bun" || value2 === "npm" || value2 === "pnpm" || value2 === "yarn";
197940
198153
  var hasBinary = (bin) => {
197941
- const result = import_node_child_process7.spawnSync("which", [bin], { stdio: "ignore" });
198154
+ const result = import_node_child_process8.spawnSync("which", [bin], { stdio: "ignore" });
197942
198155
  return result.status === 0;
197943
198156
  };
197944
198157
  var detectPackageManager = () => {
@@ -197951,13 +198164,13 @@ var detectPackageManager = () => {
197951
198164
  };
197952
198165
  var readInstalledVersion = () => {
197953
198166
  const candidates = [
197954
- import_node_path22.default.resolve(__dirname, "..", "package.json"),
197955
- import_node_path22.default.resolve(__dirname, "..", "..", "package.json"),
197956
- import_node_path22.default.resolve(__dirname, "..", "..", "..", "package.json")
198167
+ import_node_path23.default.resolve(__dirname, "..", "package.json"),
198168
+ import_node_path23.default.resolve(__dirname, "..", "..", "package.json"),
198169
+ import_node_path23.default.resolve(__dirname, "..", "..", "..", "package.json")
197957
198170
  ];
197958
198171
  for (const file of candidates) {
197959
198172
  try {
197960
- const raw = import_node_fs21.default.readFileSync(file, "utf8");
198173
+ const raw = import_node_fs22.default.readFileSync(file, "utf8");
197961
198174
  const parsed = JSON.parse(raw);
197962
198175
  if (parsed.name === PACKAGE_NAME && parsed.version) {
197963
198176
  return parsed.version;
@@ -197981,7 +198194,7 @@ var selfUpgradeCommand = async (override) => {
197981
198194
  }
197982
198195
  const args = INSTALL_ARGS[pm];
197983
198196
  console.log(`[pieui] Upgrading via ${pm}: ${pm} ${args.join(" ")}`);
197984
- const result = import_node_child_process7.spawnSync(pm, args, {
198197
+ const result = import_node_child_process8.spawnSync(pm, args, {
197985
198198
  stdio: "inherit",
197986
198199
  env: process.env
197987
198200
  });
@@ -198040,7 +198253,11 @@ var main = async () => {
198040
198253
  historyPage,
198041
198254
  historyPerPage,
198042
198255
  historyFrom,
198043
- historyTo
198256
+ historyTo,
198257
+ registryAction,
198258
+ registryPort,
198259
+ registryApiServer,
198260
+ registryOut
198044
198261
  } = args;
198045
198262
  console.log(`[pieui] CLI started with command: "${command}"`);
198046
198263
  switch (command) {
@@ -198064,9 +198281,22 @@ var main = async () => {
198064
198281
  case "self-upgrade":
198065
198282
  await selfUpgradeCommand(args.selfUpgradePm);
198066
198283
  return;
198284
+ case "registry": {
198285
+ if (registryAction !== "dev" && registryAction !== "build") {
198286
+ console.error("[pieui] Error: Supported registry subcommands: dev, build");
198287
+ printUsage();
198288
+ process.exit(1);
198289
+ }
198290
+ registryCommand(registryAction, {
198291
+ port: registryPort,
198292
+ apiServer: registryApiServer,
198293
+ out: registryOut
198294
+ });
198295
+ return;
198296
+ }
198067
198297
  case "postbuild":
198068
- console.log(`[pieui] Source directory: ${import_node_path23.default.resolve(process.cwd(), srcDir)}`);
198069
- console.log(`[pieui] Output directory: ${import_node_path23.default.resolve(process.cwd(), outDir)}`);
198298
+ console.log(`[pieui] Source directory: ${import_node_path24.default.resolve(process.cwd(), srcDir)}`);
198299
+ console.log(`[pieui] Output directory: ${import_node_path24.default.resolve(process.cwd(), outDir)}`);
198070
198300
  console.log(`[pieui] Append mode: ${append}`);
198071
198301
  await postbuildCommand(srcDir, outDir, append);
198072
198302
  return;
@@ -1,6 +1,6 @@
1
1
  import type { ParsedArgs } from './types';
2
2
  export declare const parseArgs: (argv: string[]) => ParsedArgs;
3
- export type HelpScope = 'all' | 'login' | 'create' | 'init' | 'postbuild' | 'card' | 'card-remote' | 'page' | 'self-upgrade';
3
+ export type HelpScope = 'all' | 'login' | 'create' | 'init' | 'postbuild' | 'card' | 'card-remote' | 'page' | 'registry' | 'self-upgrade';
4
4
  export declare const detectHelpScope: (argv: string[]) => HelpScope | null;
5
5
  export declare const printUsage: (scope?: HelpScope) => void;
6
6
  //# sourceMappingURL=args.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"args.d.ts","sourceRoot":"","sources":["../../src/code/args.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAOR,UAAU,EACb,MAAM,SAAS,CAAA;AA0KhB,eAAO,MAAM,SAAS,GAAI,MAAM,MAAM,EAAE,KAAG,UA8I1C,CAAA;AAED,MAAM,MAAM,SAAS,GACf,KAAK,GACL,OAAO,GACP,QAAQ,GACR,MAAM,GACN,WAAW,GACX,MAAM,GACN,aAAa,GACb,MAAM,GACN,cAAc,CAAA;AAEpB,eAAO,MAAM,eAAe,GAAI,MAAM,MAAM,EAAE,KAAG,SAAS,GAAG,IAe5D,CAAA;AA0MD,eAAO,MAAM,UAAU,GAAI,QAAO,SAAiB,SAwBlD,CAAA"}
1
+ {"version":3,"file":"args.d.ts","sourceRoot":"","sources":["../../src/code/args.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAOR,UAAU,EAEb,MAAM,SAAS,CAAA;AA0KhB,eAAO,MAAM,SAAS,GAAI,MAAM,MAAM,EAAE,KAAG,UAyK1C,CAAA;AAED,MAAM,MAAM,SAAS,GACf,KAAK,GACL,OAAO,GACP,QAAQ,GACR,MAAM,GACN,WAAW,GACX,MAAM,GACN,aAAa,GACb,MAAM,GACN,UAAU,GACV,cAAc,CAAA;AAEpB,eAAO,MAAM,eAAe,GAAI,MAAM,MAAM,EAAE,KAAG,SAAS,GAAG,IAgB5D,CAAA;AA8MD,eAAO,MAAM,UAAU,GAAI,QAAO,SAAiB,SAwBlD,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"createPieApp.d.ts","sourceRoot":"","sources":["../../../src/code/commands/createPieApp.ts"],"names":[],"mappings":"AAoOA,eAAO,MAAM,mBAAmB,GAAI,SAAS,MAAM,SAyElD,CAAA"}
1
+ {"version":3,"file":"createPieApp.d.ts","sourceRoot":"","sources":["../../../src/code/commands/createPieApp.ts"],"names":[],"mappings":"AAqOA,eAAO,MAAM,mBAAmB,GAAI,SAAS,MAAM,SAyElD,CAAA"}
@@ -0,0 +1,8 @@
1
+ type RegistryOptions = {
2
+ port?: number;
3
+ apiServer?: string;
4
+ out?: string;
5
+ };
6
+ export declare const registryCommand: (action: "dev" | "build", opts?: RegistryOptions) => void;
7
+ export {};
8
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/code/commands/registry.ts"],"names":[],"mappings":"AAyBA,KAAK,eAAe,GAAG;IACnB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,GAAG,CAAC,EAAE,MAAM,CAAA;CACf,CAAA;AA2LD,eAAO,MAAM,eAAe,GACxB,QAAQ,KAAK,GAAG,OAAO,EACvB,OAAM,eAAoB,KAC3B,IAiDF,CAAA"}
@@ -39,7 +39,12 @@ export type ParsedArgs = {
39
39
  selfUpgradePm?: string;
40
40
  dumpMetadataOut?: string;
41
41
  cardGeneratePreviewOut?: string;
42
+ registryAction?: RegistryAction;
43
+ registryPort?: number;
44
+ registryApiServer?: string;
45
+ registryOut?: string;
42
46
  };
47
+ export type RegistryAction = 'dev' | 'build';
43
48
  export type CardScaffoldOptions = {
44
49
  ajax?: boolean;
45
50
  io?: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/code/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,GAAG,MAAM,wBAAwB,CAAA;AAElD,eAAO,MAAM,iBAAiB,0BAA0B,CAAA;AACxD,eAAO,MAAM,iBAAiB,yBAAyB,CAAA;AAEvD,MAAM,MAAM,aAAa,GACnB,QAAQ,GACR,SAAS,GACT,kBAAkB,GAClB,mBAAmB,CAAA;AAEzB,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,aAAa,CAAA;AAC9C,MAAM,MAAM,UAAU,GAChB,KAAK,GACL,MAAM,GACN,MAAM,GACN,MAAM,GACN,QAAQ,GACR,aAAa,GACb,WAAW,GACX,QAAQ,GACR,eAAe,GACf,YAAY,GACZ,WAAW,GACX,kBAAkB,CAAA;AACxB,MAAM,MAAM,gBAAgB,GACtB,MAAM,GACN,MAAM,GACN,MAAM,GACN,QAAQ,GACR,SAAS,GACT,QAAQ,GACR,SAAS,CAAA;AACf,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,CAAA;AAChD,MAAM,MAAM,cAAc,GAAG,KAAK,GAAG,QAAQ,CAAA;AAE7C,MAAM,MAAM,UAAU,GAAG;IACrB,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,OAAO,CAAA;IACf,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,aAAa,CAAC,EAAE,aAAa,CAAA;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,UAAU,CAAC,EAAE,UAAU,CAAA;IACvB,UAAU,CAAC,EAAE,UAAU,CAAA;IACvB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B,gBAAgB,CAAC,EAAE,gBAAgB,CAAA;IACnC,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,UAAU,CAAC,EAAE,UAAU,CAAA;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,cAAc,CAAC,EAAE,cAAc,CAAA;IAC/B,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,sBAAsB,CAAC,EAAE,MAAM,CAAA;CAClC,CAAA;AAED,MAAM,MAAM,mBAAmB,GAAG;IAC9B,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,EAAE,CAAC,EAAE,OAAO,CAAA;IACZ,KAAK,CAAC,EAAE,OAAO,CAAA;CAClB,CAAA;AAED,MAAM,MAAM,sBAAsB,GAAG;IACjC,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,GAAG,CAAC,UAAU,CAAA;CACvB,CAAA;AAED,MAAM,MAAM,aAAa,GAAG;IACxB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,YAAY,EAAE,MAAM,CAAA;CACvB,CAAA;AAED,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;AAEhD,MAAM,MAAM,YAAY,GAAG;IACvB;;yBAEqB;IACrB,IAAI,EAAE,MAAM,CAAA;IACZ,6CAA6C;IAC7C,OAAO,EAAE,MAAM,CAAA;CAClB,CAAA;AAED,MAAM,MAAM,WAAW,GAAG;IACtB,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,YAAY,EAAE,CAAA;IACrB,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB,eAAe,EAAE,MAAM,EAAE,CAAA;IACzB,MAAM,EAAE,MAAM,EAAE,CAAA;IAChB,WAAW,EAAE,UAAU,GAAG,IAAI,CAAA;IAC9B,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE,MAAM,CAAA;IACnB,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;IAC7C,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACvC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,gBAAgB,EAAE,UAAU,GAAG,IAAI,CAAA;IACnC,QAAQ,EAAE,MAAM,EAAE,CAAA;CACrB,CAAA"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/code/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ import { Component, ReactNode } from 'react';
2
+ /**
3
+ * Error boundary + Suspense wrapper for a single lazy (code-split) card.
4
+ *
5
+ * A `React.lazy` chunk can fail to load — a flaky network, or (commonly) a
6
+ * fresh deploy that changed chunk hashes so the running tab requests a chunk
7
+ * that now 404s. A bare `<Suspense>` does NOT catch that: the error propagates
8
+ * and white-screens the tree. This boundary instead:
9
+ *
10
+ * 1. renders the card's `fallback` (its skeleton) instead of crashing,
11
+ * 2. retries the import a couple of times with backoff — remounting the
12
+ * Suspense subtree, which re-runs the loader (the module cache evicts a
13
+ * rejected promise, so the retry is a fresh attempt), and
14
+ * 3. calls `onError` so the host can recover from a stale deploy (e.g. a
15
+ * one-shot page reload).
16
+ *
17
+ * If the retries are exhausted it stays on the fallback rather than throwing,
18
+ * so one broken card never takes down the whole screen.
19
+ */
20
+ type Props = {
21
+ /** Stable key (the card name) — resets the boundary if the card changes. */
22
+ name: string;
23
+ /** Shown while loading and as the give-up state (the card's skeleton). */
24
+ fallback: ReactNode;
25
+ /** Called on each caught chunk error, after retries are scheduled. */
26
+ onError?: (error: unknown) => void;
27
+ children: ReactNode;
28
+ };
29
+ type State = {
30
+ failed: boolean;
31
+ attempt: number;
32
+ };
33
+ export default class LazyBoundary extends Component<Props, State> {
34
+ state: State;
35
+ private timer;
36
+ static getDerivedStateFromError(): Partial<State>;
37
+ componentDidCatch(error: unknown): void;
38
+ componentDidUpdate(prevProps: Props): void;
39
+ componentWillUnmount(): void;
40
+ render(): string | number | bigint | boolean | Iterable<ReactNode> | Promise<string | number | bigint | boolean | import("react").ReactPortal | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> | import("react").JSX.Element | null | undefined;
41
+ }
42
+ export {};
43
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/LazyBoundary/index.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,SAAS,EAAY,MAAM,OAAO,CAAA;AAEtD;;;;;;;;;;;;;;;;;GAiBG;AAEH,KAAK,KAAK,GAAG;IACT,4EAA4E;IAC5E,IAAI,EAAE,MAAM,CAAA;IACZ,0EAA0E;IAC1E,QAAQ,EAAE,SAAS,CAAA;IACnB,sEAAsE;IACtE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAA;IAClC,QAAQ,EAAE,SAAS,CAAA;CACtB,CAAA;AAED,KAAK,KAAK,GAAG;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAA;AAKjD,MAAM,CAAC,OAAO,OAAO,YAAa,SAAQ,SAAS,CAAC,KAAK,EAAE,KAAK,CAAC;IAC7D,KAAK,EAAE,KAAK,CAAgC;IAC5C,OAAO,CAAC,KAAK,CAA2C;IAExD,MAAM,CAAC,wBAAwB,IAAI,OAAO,CAAC,KAAK,CAAC;IAIjD,iBAAiB,CAAC,KAAK,EAAE,OAAO;IAWhC,kBAAkB,CAAC,SAAS,EAAE,KAAK;IAOnC,oBAAoB;IAIpB,MAAM;CAWT"}