@peripheries/engine 0.8.2 → 0.9.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.
- package/LICENSE +7 -0
- package/package.json +1 -1
- package/src/commands/externals.mjs +1 -1
- package/src/harness/app.mjs +1 -1
package/LICENSE
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
Copyright (c) 2026 Peripheries Studio Inc. All rights reserved.
|
|
2
|
+
|
|
3
|
+
This software is proprietary to Peripheries Studio Inc. It is published to the
|
|
4
|
+
npm registry for distribution to Peripheries Studio Inc.'s own projects. No
|
|
5
|
+
licence is granted to anyone to use, copy, modify, merge, publish, distribute,
|
|
6
|
+
sublicense or sell it, in whole or in part, without the prior written
|
|
7
|
+
permission of Peripheries Studio Inc.
|
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
const EXTERNALS=Object.freeze(["react","react/jsx-runtime","react/jsx-dev-runtime","react-dom","react-dom/client","zustand","@
|
|
1
|
+
const EXTERNALS=Object.freeze(["react","react/jsx-runtime","react/jsx-dev-runtime","react-dom","react-dom/client","zustand","@stack/store"]);export{EXTERNALS};
|
package/src/harness/app.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import{Fragment,jsx,jsxs}from"react/jsx-runtime";import"@peripheries/renderer/styles.css";import{pageRuntimeFromValues,projectCellActions}from"@peripheries/renderer/core";import{PageRenderer}from"@peripheries/renderer/react";import{getStackStore}from"@peripheries/renderer/runtime";import{FIXTURE_BASE_PROPS}from"@peripheries/renderer/testing";import{Component,isValidElement,useEffect,useMemo}from"react";import{createRoot}from"react-dom/client";const isComponent=v=>typeof v==="function"||typeof v==="object"&&v!==null&&"$$typeof"in v;function sharedBundle({specifier,module}){const components=Object.fromEntries(Object.entries(module).filter(([name,v])=>/^[A-Z]/.test(name)&&isComponent(v)));return{id:specifier,label:specifier,specifier,components,contracts:{}}}const fixtureName=path=>path.split("/").pop().replace(/\.fixtures\.tsx?$/,"");const pageKey=path=>{const m=path.match(/\/project_templates\/([^/]+)\/pages\/([^/]+)\/page\.json$/)??path.match(/\/pages\/([^/]+)\/page\.json$/);return m?m.slice(1).join("/"):path};function isJson(v){if(v===null||["string","number","boolean"].includes(typeof v))return true;if(Array.isArray(v))return v.every(isJson);if(typeof v!=="object"||isValidElement(v))return false;const proto=Object.getPrototypeOf(v);return(proto===Object.prototype||proto===null)&&Object.values(v).every(isJson)}class Boundary extends Component{state={error:null};static getDerivedStateFromError(error){return{error}}componentDidCatch(error,info){window.__ENGINE_HARNESS_ERROR=`${error.message}
|
|
2
|
-
${info.componentStack??""}`}render(){return this.state.error?jsx("pre",{role:"alert",children:this.state.error.message}):this.props.children}}function Ready({children}){useEffect(()=>{const id=requestAnimationFrame(()=>requestAnimationFrame(()=>window.__ENGINE_HARNESS_READY=true));return()=>cancelAnimationFrame(id)},[]);return jsx(Fragment,{children})}function RenderedPage({row,values,actions,baseProps,components,shared,Wrapper,statusOverride}){const runtime=useMemo(()=>{const rt=pageRuntimeFromValues(row,{values});if(statusOverride&&(statusOverride.isLoading||statusOverride.error)){const error=statusOverride.error?new Error(statusOverride.error):null;for(const cell of rt.cells)rt.cellData[cell.id]??={static:{},declared:{}};for(const own of Object.values(rt.cellData)){const keys=Object.keys(own.static).length?Object.keys(own.static):["fixture"];for(const k of keys)own.static[k]={data:void 0,isLoading:Boolean(statusOverride.isLoading),error}}}return rt},[row,values,statusOverride]);const bundles=useMemo(()=>{const
|
|
2
|
+
${info.componentStack??""}`}render(){return this.state.error?jsx("pre",{role:"alert",children:this.state.error.message}):this.props.children}}function Ready({children}){useEffect(()=>{const id=requestAnimationFrame(()=>requestAnimationFrame(()=>window.__ENGINE_HARNESS_READY=true));return()=>cancelAnimationFrame(id)},[]);return jsx(Fragment,{children})}function RenderedPage({row,values,actions,baseProps,components,shared,Wrapper,statusOverride}){const runtime=useMemo(()=>{const rt=pageRuntimeFromValues(row,{values});if(statusOverride&&(statusOverride.isLoading||statusOverride.error)){const error=statusOverride.error?new Error(statusOverride.error):null;for(const cell of rt.cells)rt.cellData[cell.id]??={static:{},declared:{}};for(const own of Object.values(rt.cellData)){const keys=Object.keys(own.static).length?Object.keys(own.static):["fixture"];for(const k of keys)own.static[k]={data:void 0,isLoading:Boolean(statusOverride.isLoading),error}}}return rt},[row,values,statusOverride]);const bundles=useMemo(()=>{const bundle={id:"harness",label:"harness",components,contracts:{}};return{scope:[bundle,...shared],forCell:()=>null}},[components,shared]);const environment=useMemo(()=>{const pageActions=Object.fromEntries(Object.keys(actions??{}).map(k=>[k,async input=>(console.info(`[harness] action ${k}`,input),{ok:true})]));window.__ENGINE_HARNESS_DIAGNOSTICS=[];return{core:{},navigate:()=>{},store:getStackStore(),actionsFor:cell=>cell.actions?projectCellActions(cell.actions,pageActions):Object.keys(pageActions).length?pageActions:void 0,onCellError:(cellId,error)=>console.error(`[harness] cell "${cellId}" failed:`,error),onDiagnostic:d=>{window.__ENGINE_HARNESS_DIAGNOSTICS.push({code:d.code,severity:d.severity,message:d.message,...d.cellId?{cellId:d.cellId}:{}});if(d.severity==="error")console.error(`[harness] ${d.code}: ${d.message}`)}}},[actions]);const page=jsx(PageRenderer,{runtime,bundles,params:{},baseProps,context:{environment:"harness"},environment});return Wrapper?jsx(Wrapper,{baseProps,children:page}):page}function pageRow(id,json){return{id,name:json.name,org_id:null,project_id:null,process_id:null,graph_node_id:null,page_type:json.page_type??null,status:"published",is_template:json.is_template??false,content:json.content??{cells:[]},layout:json.layout??{type:"stack",gap:16},metadata:json.metadata??null}}function Index({fixtures,pages}){useEffect(()=>void(window.__ENGINE_HARNESS_READY=true),[]);const link=q=>`?${q}`;return jsxs("main",{style:{fontFamily:"system-ui, sans-serif",padding:24,maxWidth:960},children:[jsx("h1",{children:"Harness"}),jsx("h2",{children:"Fixtures"}),fixtures.map(([name,scenarios])=>jsxs("section",{children:[jsx("h3",{children:name}),jsx("ul",{children:scenarios.map(s=>jsxs("li",{children:[jsx("a",{href:link(`fixture=${encodeURIComponent(name)}&scenario=${encodeURIComponent(s.name)}`),children:s.name})," \xB7 ",jsx("a",{href:link(`fixture=${encodeURIComponent(name)}&scenario=${encodeURIComponent(s.name)}&container=320`),children:"in 320px"})]},s.name))})]},name)),jsx("h2",{children:"Pages"}),jsx("ul",{children:pages.map(p=>jsx("li",{children:jsx("a",{href:link(`page=${encodeURIComponent(p)}`),children:p})},p))})]})}function mountHarness(sources){const q=new URLSearchParams(window.location.search);const components=Object.assign({},...Object.values(sources.barrels));const shared=(sources.shared??[]).map(sharedBundle);const fixtures=Object.entries(sources.fixtures).map(([path,mod])=>[fixtureName(path),[...mod.scenarios??[]]]).sort(([a],[b])=>a.localeCompare(b));const pages=Object.fromEntries(Object.entries(sources.pages).map(([path,json])=>[pageKey(path),{json,mock:sources.mocks[path.replace(/page\.json$/,"mock.json")]}]));let body;const fixture=q.get("fixture");const page=q.get("page");if(fixture){const scenario=fixtures.find(([n])=>n===fixture)?.[1].find(s=>s.name===q.get("scenario"));if(!scenario){window.__ENGINE_HARNESS_ERROR=`no scenario "${q.get("scenario")}" for ${fixture}`;body=null}else if(!isJson(scenario.props??{})){const Direct=components[fixture]??shared.find(b=>b.components[fixture])?.components[fixture];if(!Direct)window.__ENGINE_HARNESS_ERROR=`${fixture} is not exported from any barrel or shared lineage`;const baseProps={...FIXTURE_BASE_PROPS,...scenario.baseProps};const element=Direct?jsx("div",{className:"cell","data-engine-direct":"",children:jsx(Direct,{...scenario.props,baseProps})}):null;body=sources.Wrapper?jsx(sources.Wrapper,{baseProps,children:element}):element}else{const cell={id:"fixture",component:fixture,props:scenario.props??{},...scenario.data?{data:{static:scenario.data}}:{},...scenario.selections?{selections:scenario.selections}:{},...scenario.viewState?{viewState:scenario.viewState}:{},...scenario.live?{live:scenario.live}:{}};body=jsx(RenderedPage,{row:pageRow(`${fixture}/${scenario.name}`,{name:`${fixture} \xB7 ${scenario.name}`,content:{cells:[cell]}}),values:{},actions:scenario.actions,baseProps:{...FIXTURE_BASE_PROPS,...scenario.baseProps},components,shared,Wrapper:sources.Wrapper,statusOverride:scenario.status})}}else if(page){const entry=pages[page];if(!entry){window.__ENGINE_HARNESS_ERROR=`no page "${page}"`;body=null}else{const values={...entry.mock?.data};body=jsx(RenderedPage,{row:pageRow(page,entry.json),values,actions:entry.mock?.actions,baseProps:{...FIXTURE_BASE_PROPS,...entry.mock?.baseProps},components,shared,Wrapper:sources.Wrapper})}}else{body=jsx(Index,{fixtures,pages:Object.keys(pages).sort()})}const container=Number(q.get("container"))||null;const framed=container?jsx("div",{"data-engine-container":"",style:{width:container,containerType:"inline-size",outline:"1px dashed #bbb"},children:body}):body;createRoot(document.getElementById("root")).render(jsx(Boundary,{children:jsx(Ready,{children:framed})}))}export{mountHarness};
|