@delpi/react-struct-z 1.0.0-alz

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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Delpi.Kye
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,216 @@
1
+ ## πŸ—οΈ @delpi/react-struct-z
2
+
3
+ ---
4
+
5
+ [![NPM](https://img.shields.io/npm/v/@delpi/react-struct-z.svg)](https://www.npmjs.com/package/@delpi/react-struct-z)
6
+ ![Downloads](https://img.shields.io/npm/dt/@delpi/react-struct-z.svg)
7
+
8
+
9
+ [Live Demo](https://codesandbox.io/p/sandbox/c8l2pf)
10
+
11
+ ---
12
+
13
+ ## 🌟 Description
14
+
15
+ - @delpi/react-struct-z is a frontend runtime framework combining:
16
+ - React-style composable UI - module – controller – service – DI – lifecycle
17
+ - It provides a runtime orchestration layer for intents, effects, reactive stores, DI, and plugins, keeping business logic separate from UI.
18
+
19
+ > Think of it as: β€œFrontend behavior runtime, modular & testable.”
20
+
21
+ ---
22
+
23
+ ## ✨ When to Use
24
+
25
+ + Business logic should not live inside UI components
26
+ + UI only emits intents, does not orchestrate logic
27
+ + Complex async flows or multiple side effects
28
+ + Headless, testable without rendering React
29
+ + Multi-module, multi-engine architecture
30
+ + Following DDD, hexagonal, or layered frontend architecture
31
+
32
+ ---
33
+
34
+ ## πŸ“¦ Installation
35
+ ```ts
36
+ npm install @delpi/react-struct-z
37
+ ```
38
+
39
+ ---
40
+
41
+ ## 🧩 Mental Model
42
+ ```bash
43
+ UI Layer (React)
44
+ └─ emits intents
45
+ ↓
46
+ AppRuntime (FE Struct Framework)
47
+ β”œβ”€ DI Container
48
+ β”œβ”€ IntentBus + Middleware
49
+ β”œβ”€ EffectManager
50
+ β”œβ”€ Store (Reactive Runtime)
51
+ β”œβ”€ Module System
52
+ └─ Plugin System
53
+ ```
54
+
55
+ ---
56
+
57
+ ## πŸš€ Basic Usage (Headless)
58
+
59
+ #### 1️⃣ Basic Headless Example
60
+ ```ts
61
+ // counter.store.ts
62
+ import { Store } from "@delpi/react-struct-z"
63
+ export const counterStore = new Store({ value: 0 })
64
+
65
+ // counter.module.ts
66
+ export const CounterModule = {
67
+ setup(app: any) {
68
+ app.intent.on("counter/inc", () => {
69
+ counterStore.set({ value: counterStore.get().value + 1 })
70
+ })
71
+ }
72
+ }
73
+
74
+ // app.ts
75
+ import { AppRuntime, loadRemotePlugin } from "@delpi/react-struct-z"
76
+ import { CounterModule } from "./counter.module"
77
+ export const app = new AppRuntime()
78
+ CounterModule.setup(app)
79
+
80
+ // Async + Remote Plugin (if needed)
81
+ // await loadRemotePlugin({
82
+ // url: "https://cdn.myapp.com/remote-logger.js"
83
+ // }).then(plugin => app.use(plugin))
84
+
85
+ // Dispatch
86
+ app.intent.dispatch({ type: "counter/inc" })
87
+ console.log(counterStore.get().value) // 1
88
+ ```
89
+
90
+ > βœ… Quick start, headless, testable, no DI.
91
+
92
+ ----
93
+
94
+ #### 2️⃣ React Integration Example
95
+
96
+ ```ts
97
+ // counter.store.ts
98
+ import { Store } from "@delpi/react-struct-z"
99
+ export const counterStore = new Store({ value: 0 })
100
+
101
+ // counter.service.ts
102
+ import { counterStore } from "./counter.store"
103
+ // Injectable is currently no-op
104
+ export class CounterService {
105
+ constructor(private store = counterStore) {} // manual DI
106
+ increment() {
107
+ this.store.set({ value: this.store.get().value + 1 })
108
+ }
109
+ }
110
+
111
+ // counter.module.ts
112
+ import { CounterService } from "./counter.service"
113
+ import { counterStore } from "./counter.store"
114
+
115
+ export const CounterModule = {
116
+ name: "counter",
117
+ setup(app: any) {
118
+ // Resolve service manually from container
119
+ const service = app.container.resolve(CounterService)
120
+
121
+ // Namespaced intent
122
+ app.intent.on("counter/inc", () => service.increment())
123
+ }
124
+ }
125
+
126
+ // app.ts
127
+ import { AppRuntime } from "@delpi/react-struct-z"
128
+ import { CounterModule } from "./counter.module"
129
+
130
+ // Create runtime
131
+ export const app = new AppRuntime()
132
+
133
+ // Optionally register service in container
134
+ app.container.provide(CounterService, () => new CounterService())
135
+
136
+ // Setup module
137
+ CounterModule.setup(app)
138
+
139
+ // Headless dispatch
140
+ app.intent.dispatch({ type: "counter/inc" })
141
+ console.log("Counter value:", app.container.resolve(CounterService)["store"].get().value)
142
+
143
+ // CounterView.tsx
144
+ import React from "react"
145
+ import { useStore, useIntent } from "@delpi/react-struct-z"
146
+ import { counterStore } from "./counter.store"
147
+
148
+ export function CounterView() {
149
+ const state = useStore(counterStore)
150
+ const dispatch = useIntent("counter") // namespaced
151
+
152
+ return (
153
+ <button onClick={() => dispatch({ type: "counter/inc" })}>
154
+ Count: {state.value}
155
+ </button>
156
+ )
157
+ }
158
+
159
+ // main.tsx
160
+ import React from "react"
161
+ import { createRoot } from "react-dom/client"
162
+ import { RuntimeProvider } from "@delpi/react-struct-z"
163
+ import { app } from "./app"
164
+ import { CounterView } from "./CounterView"
165
+
166
+ createRoot(document.getElementById("root")!).render(
167
+ <RuntimeProvider runtime={app}>
168
+ <CounterView />
169
+ </RuntimeProvider>
170
+ )
171
+ ```
172
+ > βœ… Full React integration, composable UI, runtime orchestration + store + intent.
173
+
174
+ ---
175
+
176
+ ## πŸ§ͺ Testing Example
177
+ ```ts
178
+ import { AppRuntime, Store } from "@delpi/react-struct-z"
179
+
180
+ test("counter increments", () => {
181
+ const app = new AppRuntime()
182
+ const store = new Store({ value: 0 })
183
+
184
+ app.intent.on("inc", () => store.set({ value: store.get().value + 1 }))
185
+
186
+ app.intent.dispatch({ type: "inc" })
187
+ app.intent.dispatch({ type: "inc" })
188
+
189
+ expect(store.get().value).toBe(2)
190
+ })
191
+ ```
192
+
193
+ ---
194
+
195
+ ## βš™οΈ Key Features
196
+ | Feature / Capability | FE Struct Framework | Next.js | Remix | Gatsby |
197
+ | ---------------------------- | -------------------------- | ---------------------------------- | ------------------------ | ------------------------ |
198
+ | React-oriented | βœ… Full React | βœ… Full React | βœ… Full React | βœ… Full React |
199
+ | Intent / Action-based | βœ… Scoped intents | ❌ | ❌ | ❌ |
200
+ | Async flows built-in | βœ… Built-in + effects | ⚠️ Needs fetcher / hooks | ⚠️ Needs fetcher / hooks | ⚠️ Needs fetcher / hooks |
201
+ | Side effects management | βœ… First-class | ⚠️ Via React hooks | ⚠️ Via React hooks | ⚠️ Via React hooks |
202
+ | Reactive Store | βœ… Store + computed | ❌ Only React state | ❌ Only React state | ❌ Only React state |
203
+ | Module System / DI | βœ… Modules + lifecycle + DI | ❌ Not supported | ❌ Not supported | ❌ Not supported |
204
+ | Computed / Derived state | βœ… Sync + Async | ❌ Only via useMemo / custom hooks | ❌ | ❌ |
205
+ | Scoped / Namespaced Intents | βœ… Yes | ❌ | ❌ | ❌ |
206
+ | Headless / Testable | βœ… Fully headless | ⚠️ Needs mock SSR | ⚠️ Needs mock SSR | ⚠️ Needs mock SSR |
207
+ | Routing / Navigation | ❌ Not supported | βœ… Built-in | βœ… Built-in | βœ… Built-in |
208
+ | SSR / SSG | ❌ Not supported | βœ… Built-in | βœ… Built-in | βœ… Built-in |
209
+ | Rendering Layer | ❌ Not supported | βœ… Full rendering | βœ… Full rendering | βœ… Full rendering |
210
+ | Build / Bundling | ❌ Not included | βœ… Built-in | βœ… Built-in | βœ… Built-in |
211
+
212
+ ---
213
+
214
+ ## πŸ“œ License
215
+
216
+ MIT
@@ -0,0 +1,20 @@
1
+ import { Container } from "@/di/container";
2
+ import { IntentBus } from "@/intent/IntentBus";
3
+ import { EffectManager } from "@/effect/EffectManager";
4
+ import { RuntimePlugin } from "@/plugin/Plugin";
5
+ import { Module } from "@/module/types";
6
+ export declare class AppRuntime {
7
+ container: Container;
8
+ intent: IntentBus;
9
+ effect: EffectManager;
10
+ private modules;
11
+ use(plugin: RuntimePlugin): void;
12
+ $on: (type: string, handler: Function) => void;
13
+ $emit: (intent: import("..").Intent) => Promise<void>;
14
+ $onIntent: (scope: string, type: string, handler: Function) => void;
15
+ $emitIntent: (scope: string, type: string, payload?: any) => Promise<void>;
16
+ useModule(module: Module): void;
17
+ initModules(): Promise<void>;
18
+ destroyModules(): void;
19
+ getModule<T extends Module = Module>(name: string): T | undefined;
20
+ }
@@ -0,0 +1,2 @@
1
+ import { AppRuntime } from "./AppRuntime";
2
+ export declare function createApp(): AppRuntime;
@@ -0,0 +1 @@
1
+ export type Constructor<T = any> = new (...args: any[]) => T;
@@ -0,0 +1,5 @@
1
+ import { Constructor } from "@/core/types";
2
+ export declare class Container {
3
+ private instances;
4
+ resolve<T>(token: Constructor<T>): T;
5
+ }
@@ -0,0 +1 @@
1
+ export declare function Injectable(): () => void;
@@ -0,0 +1,3 @@
1
+ export declare class EffectManager {
2
+ run(effect: () => Promise<any>): Promise<any>;
3
+ }
@@ -0,0 +1 @@
1
+ export type Effect<T = any> = () => Promise<T>;
@@ -0,0 +1 @@
1
+ "use strict";require("reflect-metadata");var t=require("react"),e=require("react/jsx-runtime");class s{constructor(){this.instances=new Map}resolve(t){if(!this.instances.has(t)){const e=(Reflect.getMetadata("design:paramtypes",t)||[]).map(t=>this.resolve(t));this.instances.set(t,new t(...e))}return this.instances.get(t)}}class n{constructor(){this.handlers=new Map,this.middlewares=[]}use(t){this.middlewares.push(t)}on(t,e){const s=this.handlers.get(t)||[];s.push(e),this.handlers.set(t,s)}async dispatch(t){const e={intent:t,metadata:{}};let s=-1;const n=async i=>{var o;if(i<=s)throw new Error("next() called multiple times");s=i;const r=this.middlewares[i];r?await r(e,()=>n(i+1)):null===(o=this.handlers.get(t.type))||void 0===o||o.forEach(e=>e(t))};await n(0)}onScoped(t,e,s){return this.on(`${t}/${e}`,s)}dispatchScoped(t,e,s){return this.dispatch({type:`${t}/${e}`,payload:s})}}class i{async run(t){return t()}}class o{constructor(){this.container=new s,this.intent=new n,this.effect=new i,this.modules=new Map,this.$on=this.intent.on.bind(this.intent),this.$emit=this.intent.dispatch.bind(this.intent),this.$onIntent=this.intent.onScoped.bind(this.intent),this.$emitIntent=this.intent.dispatchScoped.bind(this.intent)}use(t){t.setup(this)}useModule(t){this.modules.set(t.name,t)}async initModules(){this.modules.forEach(t=>{var e,s;null===(e=t.dependencies)||void 0===e||e.forEach(e=>{var s;const n=this.modules.get(e);null===(s=null==n?void 0:n.onModuleLoaded)||void 0===s||s.call(n,t)}),t.setup(this),null===(s=t.onInit)||void 0===s||s.call(t,this)})}destroyModules(){this.modules.forEach(t=>{var e;return null===(e=t.onDestroy)||void 0===e?void 0:e.call(t)})}getModule(t){return this.modules.get(t)}}const r=t.createContext(null),a=()=>{const e=t.useContext(r);if(!e)throw new Error("No Runtime");return e};exports.AppRuntime=o,exports.Module=function(t){return function(e){e.__moduleOptions=t}},exports.ObservabilityPlugin=class{setup(t){t.intent.use(async(t,e)=>{const s=performance.now();try{await e(),console.log("[Intent]",t.intent.type,"OK",performance.now()-s)}catch(e){throw console.error("[Intent]",t.intent.type,"ERR",e),e}})}},exports.RuntimeProvider=({runtime:t,children:s})=>e.jsx(r.Provider,{value:t,children:s}),exports.Store=class{constructor(t){this.state=t,this.listeners=new Set,this.computedMap=new Map,this.asyncComputedMap=new Map,this.asyncComputedCache=new Map}get(){return this.state}set(t){this.state=Object.assign(Object.assign({},this.state),t),this.updateComputed(),this.listeners.forEach(t=>t(this.state))}subscribe(t){return this.listeners.add(t),()=>this.listeners.delete(t)}computed(t,e){this.computedMap.set(t,e)}computedAsync(t,e){this.asyncComputedMap.set(t,e),this.updateAsyncComputed(t)}getComputed(t){var e,s;return null!==(s=null===(e=this.computedMap.get(t))||void 0===e?void 0:e(this.state))&&void 0!==s?s:this.asyncComputedCache.get(t)}updateComputed(){this.computedMap.forEach((t,e)=>t(this.state))}async updateAsyncComputed(t){const e=this.asyncComputedMap.get(t);if(e){const s=await e(this.state);this.asyncComputedCache.set(t,s),this.listeners.forEach(t=>t(this.state))}}},exports.createApp=function(){return new o},exports.createModule=function(t){return t},exports.createPluginContext=function(t){return{intent:{tap(e){t.intent.use(async(t,s)=>{e(t.intent),await s()})}},effect:{track(t){}},store:{observe(t){}}}},exports.loadRemotePlugin=async function(t){const e=await import(t.url),s=t.exportName?e[t.exportName]:e.default;if(!s)throw new Error(`Remote plugin not found: ${t.exportName||"default"}`);const n="function"==typeof s?new s:s;if(!n.manifest||!n.setup)throw new Error("Invalid RuntimePlugin");return n},exports.useComputed=function(e,s){return t.useSyncExternalStore(e.subscribe.bind(e),()=>e.getComputed(s))},exports.useEffectIntent=function(t,e){const s=a();return()=>s.intent.dispatch({type:t,payload:e})},exports.useIntent=function(t){const e=a();return s=>{const n=t?`${t}/${s.type}`:s.type;e.intent.dispatch({type:n,payload:s.payload})}},exports.useModule=function(t){return a().container.resolve(t)},exports.useRuntime=a,exports.useStore=function(e){return t.useSyncExternalStore(e.subscribe.bind(e),()=>e.get())};
@@ -0,0 +1,21 @@
1
+ import "reflect-metadata";
2
+ export { createApp } from "@/app/createApp";
3
+ export { AppRuntime } from "@/app/AppRuntime";
4
+ export { createModule } from "@/module/createModule";
5
+ export type { Module as ModuleType } from "@/module/types";
6
+ export { Module } from "@/module/decorator";
7
+ export type { ModuleOptions } from "@/module/decorator";
8
+ export type { Intent } from "@/intent/types";
9
+ export type { IntentMiddleware } from "@/intent/middleware";
10
+ export { Store } from "@/store/Store";
11
+ export { useStore } from "@/store/useStore";
12
+ export { loadRemotePlugin } from "@/plugin/remote/remotePluginLoader";
13
+ export type { RemotePluginConfig } from "@/plugin/remote/remotePluginLoader";
14
+ export type { RuntimePlugin } from "@/plugin/Plugin";
15
+ export type { PluginContext } from "@/plugin/PluginContext";
16
+ export type { PluginManifest, PluginCapability } from "@/plugin/PluginManifest";
17
+ export { createPluginContext } from "@/plugin/createPluginContext";
18
+ export { ObservabilityPlugin } from "@/plugin/observability";
19
+ export { RuntimeProvider, useRuntime } from "@/react/RuntimeProvider";
20
+ export { useIntent } from "@/react/useIntent";
21
+ export { useComputed, useEffectIntent, useModule } from "@/react/hooks";
@@ -0,0 +1 @@
1
+ import"reflect-metadata";import{useSyncExternalStore as t,createContext as e,useContext as n}from"react";import{jsx as s}from"react/jsx-runtime";class i{constructor(){this.instances=new Map}resolve(t){if(!this.instances.has(t)){const e=(Reflect.getMetadata("design:paramtypes",t)||[]).map(t=>this.resolve(t));this.instances.set(t,new t(...e))}return this.instances.get(t)}}class o{constructor(){this.handlers=new Map,this.middlewares=[]}use(t){this.middlewares.push(t)}on(t,e){const n=this.handlers.get(t)||[];n.push(e),this.handlers.set(t,n)}async dispatch(t){const e={intent:t,metadata:{}};let n=-1;const s=async i=>{var o;if(i<=n)throw new Error("next() called multiple times");n=i;const a=this.middlewares[i];a?await a(e,()=>s(i+1)):null===(o=this.handlers.get(t.type))||void 0===o||o.forEach(e=>e(t))};await s(0)}onScoped(t,e,n){return this.on(`${t}/${e}`,n)}dispatchScoped(t,e,n){return this.dispatch({type:`${t}/${e}`,payload:n})}}class a{async run(t){return t()}}class r{constructor(){this.container=new i,this.intent=new o,this.effect=new a,this.modules=new Map,this.$on=this.intent.on.bind(this.intent),this.$emit=this.intent.dispatch.bind(this.intent),this.$onIntent=this.intent.onScoped.bind(this.intent),this.$emitIntent=this.intent.dispatchScoped.bind(this.intent)}use(t){t.setup(this)}useModule(t){this.modules.set(t.name,t)}async initModules(){this.modules.forEach(t=>{var e,n;null===(e=t.dependencies)||void 0===e||e.forEach(e=>{var n;const s=this.modules.get(e);null===(n=null==s?void 0:s.onModuleLoaded)||void 0===n||n.call(s,t)}),t.setup(this),null===(n=t.onInit)||void 0===n||n.call(t,this)})}destroyModules(){this.modules.forEach(t=>{var e;return null===(e=t.onDestroy)||void 0===e?void 0:e.call(t)})}getModule(t){return this.modules.get(t)}}function c(){return new r}function u(t){return t}function h(t){return function(e){e.__moduleOptions=t}}class d{constructor(t){this.state=t,this.listeners=new Set,this.computedMap=new Map,this.asyncComputedMap=new Map,this.asyncComputedCache=new Map}get(){return this.state}set(t){this.state=Object.assign(Object.assign({},this.state),t),this.updateComputed(),this.listeners.forEach(t=>t(this.state))}subscribe(t){return this.listeners.add(t),()=>this.listeners.delete(t)}computed(t,e){this.computedMap.set(t,e)}computedAsync(t,e){this.asyncComputedMap.set(t,e),this.updateAsyncComputed(t)}getComputed(t){var e,n;return null!==(n=null===(e=this.computedMap.get(t))||void 0===e?void 0:e(this.state))&&void 0!==n?n:this.asyncComputedCache.get(t)}updateComputed(){this.computedMap.forEach((t,e)=>t(this.state))}async updateAsyncComputed(t){const e=this.asyncComputedMap.get(t);if(e){const n=await e(this.state);this.asyncComputedCache.set(t,n),this.listeners.forEach(t=>t(this.state))}}}function p(e){return t(e.subscribe.bind(e),()=>e.get())}async function l(t){const e=await import(t.url),n=t.exportName?e[t.exportName]:e.default;if(!n)throw new Error(`Remote plugin not found: ${t.exportName||"default"}`);const s="function"==typeof n?new n:n;if(!s.manifest||!s.setup)throw new Error("Invalid RuntimePlugin");return s}function m(t){return{intent:{tap(e){t.intent.use(async(t,n)=>{e(t.intent),await n()})}},effect:{track(t){}},store:{observe(t){}}}}class f{setup(t){t.intent.use(async(t,e)=>{const n=performance.now();try{await e(),console.log("[Intent]",t.intent.type,"OK",performance.now()-n)}catch(e){throw console.error("[Intent]",t.intent.type,"ERR",e),e}})}}const y=e(null),w=({runtime:t,children:e})=>s(y.Provider,{value:t,children:e}),v=()=>{const t=n(y);if(!t)throw new Error("No Runtime");return t};function g(t){const e=v();return n=>{const s=t?`${t}/${n.type}`:n.type;e.intent.dispatch({type:s,payload:n.payload})}}function M(t){return v().container.resolve(t)}function b(t,e){const n=v();return()=>n.intent.dispatch({type:t,payload:e})}function C(e,n){return t(e.subscribe.bind(e),()=>e.getComputed(n))}export{r as AppRuntime,h as Module,f as ObservabilityPlugin,w as RuntimeProvider,d as Store,c as createApp,u as createModule,m as createPluginContext,l as loadRemotePlugin,C as useComputed,b as useEffectIntent,g as useIntent,M as useModule,v as useRuntime,p as useStore};
@@ -0,0 +1 @@
1
+ !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("reflect-metadata"),require("react"),require("react/jsx-runtime")):"function"==typeof define&&define.amd?define(["exports","reflect-metadata","react","react/jsx-runtime"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).ReactStruct={},null,t.react,t.jsxRuntime)}(this,function(t,e,n,s){"use strict";class i{constructor(){this.instances=new Map}resolve(t){if(!this.instances.has(t)){const e=(Reflect.getMetadata("design:paramtypes",t)||[]).map(t=>this.resolve(t));this.instances.set(t,new t(...e))}return this.instances.get(t)}}class o{constructor(){this.handlers=new Map,this.middlewares=[]}use(t){this.middlewares.push(t)}on(t,e){const n=this.handlers.get(t)||[];n.push(e),this.handlers.set(t,n)}async dispatch(t){const e={intent:t,metadata:{}};let n=-1;const s=async i=>{var o;if(i<=n)throw new Error("next() called multiple times");n=i;const a=this.middlewares[i];a?await a(e,()=>s(i+1)):null===(o=this.handlers.get(t.type))||void 0===o||o.forEach(e=>e(t))};await s(0)}onScoped(t,e,n){return this.on(`${t}/${e}`,n)}dispatchScoped(t,e,n){return this.dispatch({type:`${t}/${e}`,payload:n})}}class a{async run(t){return t()}}class r{constructor(){this.container=new i,this.intent=new o,this.effect=new a,this.modules=new Map,this.$on=this.intent.on.bind(this.intent),this.$emit=this.intent.dispatch.bind(this.intent),this.$onIntent=this.intent.onScoped.bind(this.intent),this.$emitIntent=this.intent.dispatchScoped.bind(this.intent)}use(t){t.setup(this)}useModule(t){this.modules.set(t.name,t)}async initModules(){this.modules.forEach(t=>{var e,n;null===(e=t.dependencies)||void 0===e||e.forEach(e=>{var n;const s=this.modules.get(e);null===(n=null==s?void 0:s.onModuleLoaded)||void 0===n||n.call(s,t)}),t.setup(this),null===(n=t.onInit)||void 0===n||n.call(t,this)})}destroyModules(){this.modules.forEach(t=>{var e;return null===(e=t.onDestroy)||void 0===e?void 0:e.call(t)})}getModule(t){return this.modules.get(t)}}const u=n.createContext(null),c=()=>{const t=n.useContext(u);if(!t)throw new Error("No Runtime");return t};t.AppRuntime=r,t.Module=function(t){return function(e){e.__moduleOptions=t}},t.ObservabilityPlugin=class{setup(t){t.intent.use(async(t,e)=>{const n=performance.now();try{await e(),console.log("[Intent]",t.intent.type,"OK",performance.now()-n)}catch(e){throw console.error("[Intent]",t.intent.type,"ERR",e),e}})}},t.RuntimeProvider=({runtime:t,children:e})=>s.jsx(u.Provider,{value:t,children:e}),t.Store=class{constructor(t){this.state=t,this.listeners=new Set,this.computedMap=new Map,this.asyncComputedMap=new Map,this.asyncComputedCache=new Map}get(){return this.state}set(t){this.state=Object.assign(Object.assign({},this.state),t),this.updateComputed(),this.listeners.forEach(t=>t(this.state))}subscribe(t){return this.listeners.add(t),()=>this.listeners.delete(t)}computed(t,e){this.computedMap.set(t,e)}computedAsync(t,e){this.asyncComputedMap.set(t,e),this.updateAsyncComputed(t)}getComputed(t){var e,n;return null!==(n=null===(e=this.computedMap.get(t))||void 0===e?void 0:e(this.state))&&void 0!==n?n:this.asyncComputedCache.get(t)}updateComputed(){this.computedMap.forEach((t,e)=>t(this.state))}async updateAsyncComputed(t){const e=this.asyncComputedMap.get(t);if(e){const n=await e(this.state);this.asyncComputedCache.set(t,n),this.listeners.forEach(t=>t(this.state))}}},t.createApp=function(){return new r},t.createModule=function(t){return t},t.createPluginContext=function(t){return{intent:{tap(e){t.intent.use(async(t,n)=>{e(t.intent),await n()})}},effect:{track(t){}},store:{observe(t){}}}},t.loadRemotePlugin=async function(t){const e=await import(t.url),n=t.exportName?e[t.exportName]:e.default;if(!n)throw new Error(`Remote plugin not found: ${t.exportName||"default"}`);const s="function"==typeof n?new n:n;if(!s.manifest||!s.setup)throw new Error("Invalid RuntimePlugin");return s},t.useComputed=function(t,e){return n.useSyncExternalStore(t.subscribe.bind(t),()=>t.getComputed(e))},t.useEffectIntent=function(t,e){const n=c();return()=>n.intent.dispatch({type:t,payload:e})},t.useIntent=function(t){const e=c();return n=>{const s=t?`${t}/${n.type}`:n.type;e.intent.dispatch({type:s,payload:n.payload})}},t.useModule=function(t){return c().container.resolve(t)},t.useRuntime=c,t.useStore=function(t){return n.useSyncExternalStore(t.subscribe.bind(t),()=>t.get())}});
@@ -0,0 +1,11 @@
1
+ import { Intent } from "./types";
2
+ import { IntentMiddleware } from "./middleware";
3
+ export declare class IntentBus {
4
+ private handlers;
5
+ private middlewares;
6
+ use(mw: IntentMiddleware): void;
7
+ on(type: string, handler: Function): void;
8
+ dispatch(intent: Intent): Promise<void>;
9
+ onScoped(scope: string, type: string, handler: Function): void;
10
+ dispatchScoped(scope: string, type: string, payload?: any): Promise<void>;
11
+ }
@@ -0,0 +1,6 @@
1
+ import { Intent } from "./types";
2
+ export type IntentContext = {
3
+ intent: Intent;
4
+ metadata: Record<string, any>;
5
+ };
6
+ export type IntentMiddleware = (ctx: IntentContext, next: () => Promise<void>) => Promise<void>;
@@ -0,0 +1,4 @@
1
+ export interface Intent<T = any> {
2
+ type: string;
3
+ payload?: T;
4
+ }
@@ -0,0 +1,2 @@
1
+ import { AppRuntime } from "@/app/AppRuntime";
2
+ export declare function loadModule(app: AppRuntime, moduleClass: any): Promise<any>;
@@ -0,0 +1,4 @@
1
+ import { AppRuntime } from "@/app/AppRuntime";
2
+ import { Module } from "./types";
3
+ export declare function createModule(module: Module): Module;
4
+ export declare function initModule(app: AppRuntime, module: Module): void;
@@ -0,0 +1,5 @@
1
+ export interface ModuleOptions {
2
+ imports?: any[];
3
+ providers?: any[];
4
+ }
5
+ export declare function Module(options: ModuleOptions): (constructor: any) => void;
@@ -0,0 +1,9 @@
1
+ import { AppRuntime } from "@/app/AppRuntime";
2
+ export interface Module {
3
+ name: string;
4
+ dependencies?: string[];
5
+ setup(app: AppRuntime): void;
6
+ onInit?(app: AppRuntime): void;
7
+ onDestroy?(): void;
8
+ onModuleLoaded?(depModule: any): void;
9
+ }
@@ -0,0 +1,5 @@
1
+ import { AppRuntime } from "@/app/AppRuntime";
2
+ export interface RuntimePlugin {
3
+ setup(app: AppRuntime): void;
4
+ teardown?(): void;
5
+ }
@@ -0,0 +1,12 @@
1
+ import { Intent } from "@/intent/types";
2
+ export interface PluginContext {
3
+ intent: {
4
+ tap(fn: (intent: Intent) => void): void;
5
+ };
6
+ effect: {
7
+ track(fn: (name: string, duration: number) => void): void;
8
+ };
9
+ store: {
10
+ observe(fn: (storeId: string, nextState: any) => void): void;
11
+ };
12
+ }
@@ -0,0 +1,6 @@
1
+ import { RuntimePlugin } from "./RuntimePlugin";
2
+ export declare class PluginManager {
3
+ private plugins;
4
+ register(plugin: RuntimePlugin): void;
5
+ list(): import("./PluginManifest").PluginManifest[];
6
+ }
@@ -0,0 +1,17 @@
1
+ export type PluginCapability = "intent" | "effect" | "store" | "ui" | "devtools";
2
+ export interface PluginManifest {
3
+ id: string;
4
+ name: string;
5
+ version: string;
6
+ description?: string;
7
+ author?: string;
8
+ homepage?: string;
9
+ license?: string;
10
+ capabilities: PluginCapability[];
11
+ runtime: {
12
+ minVersion: string;
13
+ };
14
+ pricing?: {
15
+ type: "free" | "paid" | "trial";
16
+ };
17
+ }
@@ -0,0 +1,7 @@
1
+ import { AppRuntime } from "@/app/AppRuntime";
2
+ import { PluginManifest } from "./PluginManifest";
3
+ export interface RuntimePlugin {
4
+ manifest: PluginManifest;
5
+ setup(app: AppRuntime): void;
6
+ teardown?(): void;
7
+ }
@@ -0,0 +1,3 @@
1
+ import { AppRuntime } from "@/app/AppRuntime";
2
+ import { PluginContext } from "./PluginContext";
3
+ export declare function createPluginContext(app: AppRuntime): PluginContext;
@@ -0,0 +1,5 @@
1
+ import { AppRuntime } from "@/app/AppRuntime";
2
+ import { RuntimePlugin } from "@/plugin/Plugin";
3
+ export declare class ObservabilityPlugin implements RuntimePlugin {
4
+ setup(app: AppRuntime): void;
5
+ }
@@ -0,0 +1,6 @@
1
+ import { RuntimePlugin } from "../RuntimePlugin";
2
+ export type RemotePluginConfig = {
3
+ url: string;
4
+ exportName?: string;
5
+ };
6
+ export declare function loadRemotePlugin(config: RemotePluginConfig): Promise<RuntimePlugin>;
@@ -0,0 +1,7 @@
1
+ import React from "react";
2
+ import { AppRuntime } from "@/app/AppRuntime";
3
+ export declare const RuntimeProvider: React.FC<{
4
+ runtime: AppRuntime;
5
+ children: React.ReactNode;
6
+ }>;
7
+ export declare const useRuntime: () => AppRuntime;
@@ -0,0 +1,6 @@
1
+ export declare function useModule(moduleClass: any): unknown;
2
+ export declare function useEffectIntent(intentType: string, payload?: any): () => Promise<void>;
3
+ export declare function useComputed<T>(store: {
4
+ getComputed: (key: string) => T;
5
+ subscribe: any;
6
+ }, key: string): T;
@@ -0,0 +1,4 @@
1
+ export declare function useIntent(scope?: string): (intent: {
2
+ type: string;
3
+ payload?: any;
4
+ }) => void;
@@ -0,0 +1,20 @@
1
+ type Listener<T> = (state: T) => void;
2
+ type ComputedFn<T> = (state: T) => any;
3
+ type AsyncComputedFn<T> = (state: T) => Promise<any>;
4
+ export declare class Store<T> {
5
+ private state;
6
+ private listeners;
7
+ private computedMap;
8
+ private asyncComputedMap;
9
+ private asyncComputedCache;
10
+ constructor(state: T);
11
+ get(): T;
12
+ set(partial: Partial<T>): void;
13
+ subscribe(fn: Listener<T>): () => boolean;
14
+ computed(key: string, fn: ComputedFn<T>): void;
15
+ computedAsync(key: string, fn: AsyncComputedFn<T>): void;
16
+ getComputed(key: string): any;
17
+ private updateComputed;
18
+ private updateAsyncComputed;
19
+ }
20
+ export {};
@@ -0,0 +1,2 @@
1
+ import { Store } from "./Store";
2
+ export declare function useStore<T>(store: Store<T>): T;
package/package.json ADDED
@@ -0,0 +1,85 @@
1
+ {
2
+ "name": "@delpi/react-struct-z",
3
+ "version": "1.0.0-alz",
4
+ "description": "React-oriented modular framework for intent-driven orchestration, reactive store, effects, and DI-enabled modules",
5
+ "license": "MIT",
6
+ "author": "Delpi.Kye",
7
+ "type": "module",
8
+ "sideEffects": false,
9
+ "main": "build/index.cjs.js",
10
+ "module": "build/index.esm.js",
11
+ "types": "build/index.d.ts",
12
+ "exports": {
13
+ ".": {
14
+ "types": "./build/index.d.ts",
15
+ "import": "./build/index.esm.js",
16
+ "require": "./build/index.cjs.js"
17
+ }
18
+ },
19
+ "files": [
20
+ "build"
21
+ ],
22
+ "scripts": {
23
+ "clean": "rimraf build",
24
+ "build": "rollup -c",
25
+ "cb": "npm run clean && npm run build",
26
+ "prepublishOnly": "npm run cb"
27
+ },
28
+ "repository": {
29
+ "type": "git",
30
+ "url": "https://github.com/delpikye-v/react-struct.git"
31
+ },
32
+ "homepage": "https://github.com/delpikye-v/react-struct#readme",
33
+ "bugs": {
34
+ "url": "https://github.com/delpikye-v/react-struct/issues"
35
+ },
36
+ "keywords": [
37
+ "react",
38
+ "react-framework",
39
+ "intent",
40
+ "intent-engine",
41
+ "orchestration",
42
+ "modular",
43
+ "module-system",
44
+ "computed-graph",
45
+ "state-engine",
46
+ "effect-pipeline",
47
+ "di-container",
48
+ "plugin-system",
49
+ "side-effects",
50
+ "async-flow",
51
+ "reactive-store",
52
+ "ddd",
53
+ "hexagonal",
54
+ "frontend-architecture"
55
+ ],
56
+ "devDependencies": {
57
+ "@rollup/plugin-commonjs": "^25.0.0",
58
+ "@rollup/plugin-node-resolve": "^15.2.3",
59
+ "@rollup/plugin-terser": "^0.4.4",
60
+
61
+ "rollup": "^4.9.6",
62
+ "rollup-plugin-typescript2": "^0.36.0",
63
+
64
+ "typescript": "^5.3.3",
65
+ "tslib": "^2.6.2",
66
+ "rimraf": "^5.0.5",
67
+
68
+ "react": "^18.2.0",
69
+ "react-dom": "^18.2.0",
70
+ "@types/react": "^18.2.45",
71
+ "@types/react-dom": "^18.2.18"
72
+ },
73
+
74
+ "peerDependencies": {
75
+ "react": ">=16.8",
76
+ "react-dom": ">=16.8"
77
+ },
78
+
79
+ "dependencies": {
80
+ "reflect-metadata": "^0.1.13"
81
+ },
82
+ "publishConfig": {
83
+ "access": "public"
84
+ }
85
+ }