intentx-solid 0.0.1

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/README.md ADDED
@@ -0,0 +1,263 @@
1
+ ## πŸ”·βš‘ intentx-solid
2
+
3
+ [![NPM](https://img.shields.io/npm/v/intentx-solid.svg)](https://www.npmjs.com/package/intentx-solid) ![Downloads](https://img.shields.io/npm/dt/intentx-solid.svg)
4
+
5
+ <a href="https://codesandbox.io/p/devbox/5d4shj" target="_blank">LIVE EXAMPLE</a>
6
+
7
+ ---
8
+
9
+ `intentx-solid` connects the headless **LogicRuntime engine** with Solid’s fine-grained reactive system.
10
+
11
+ It does not replace Solid’s state primitives.
12
+ It orchestrates business logic outside the component tree.
13
+
14
+ > It is a bridge between deterministic logic and Solid’s reactive UI.
15
+
16
+ ---
17
+
18
+ ## ✨ Why intentx-solid?
19
+
20
+ Use it when your UI starts to feel like business logic.
21
+
22
+ βœ… Complex async workflows
23
+ βœ… Intent-based architecture
24
+ βœ… Microfrontend communication
25
+ βœ… Testable business logic
26
+ βœ… Cross-framework runtime reuse
27
+
28
+ Avoid it when:
29
+
30
+ ❌ You only need simple `createSignal`
31
+ ❌ You want reducer-style state
32
+ ❌ Your state is purely local UI
33
+
34
+ ---
35
+
36
+ ## 🧠 Mental Model
37
+ ```txt
38
+ UI Event
39
+ ↓
40
+ emit(intent)
41
+ ↓
42
+ intent handler
43
+ ↓
44
+ setState
45
+ ↓
46
+ computed re-evaluates
47
+ ↓
48
+ Solid store updates
49
+ ↓
50
+ Fine-grained reactivity updates UI
51
+ ```
52
+
53
+ ---
54
+
55
+ ## πŸ“¦ Installation
56
+
57
+ ``` bash
58
+ npm install intentx-solid
59
+ ```
60
+
61
+ ---
62
+
63
+ ## 🧩 Core Logic (Framework-Agnostic)
64
+
65
+ ``` ts
66
+ import { createLogic } from "intentx-runtime"
67
+
68
+ export const counterLogic = createLogic({
69
+ name: "counter",
70
+
71
+ state: {
72
+ count: 0
73
+ },
74
+
75
+ computed: {
76
+ double: ({ state }) => state.count * 2
77
+ },
78
+
79
+ actions: ({ setState }) => ({
80
+ inc() {
81
+ setState(d => {
82
+ d.count++
83
+ })
84
+ }
85
+ })
86
+ })
87
+ ```
88
+
89
+ ---
90
+
91
+ ## πŸ”Œ Solid Adapter
92
+
93
+ ``` ts
94
+ export { useLogic }
95
+ ```
96
+
97
+ ---
98
+
99
+ ## πŸš€ Usage
100
+
101
+ ``` tsx
102
+ import { useLogic } from "intentx-solid"
103
+ import { counterLogic } from "./counter.logic"
104
+
105
+ export default function Counter() {
106
+ const counter = useLogic(counterLogic)
107
+
108
+ return (
109
+ <>
110
+ <button onClick={counter.actions.inc}>
111
+ {counter.store.count}
112
+ </button>
113
+
114
+ <p>Double: {counter.store.double}</p>
115
+ </>
116
+ )
117
+ }
118
+ ```
119
+
120
+ No wrapper components.
121
+ No providers required (unless you want shared context).
122
+
123
+ ---
124
+
125
+ ## πŸ“¦ What `useLogic` Returns
126
+
127
+ ``` ts
128
+ const counter = useLogic(counterLogic)
129
+ ```
130
+
131
+ ```txt
132
+ {
133
+ runtime,
134
+ store,
135
+ state,
136
+ actions,
137
+ emit
138
+ }
139
+ ```
140
+
141
+ πŸ”₯ Important
142
+
143
+ - store is readonly
144
+
145
+ - Mutations must go through actions
146
+
147
+ - Solid reactivity remains fine-grained
148
+
149
+ ---
150
+
151
+ ## πŸ“‘ Scoped Bus
152
+
153
+ ``` ts
154
+ useLogic(logic, {
155
+ sharedBus: true
156
+ })
157
+ ```
158
+
159
+ Scoped:
160
+
161
+ ``` ts
162
+ useLogic(logic, {
163
+ scope: "dashboard",
164
+ sharedBus: true
165
+ })
166
+ ```
167
+
168
+ Custom bus:
169
+
170
+ ``` ts
171
+ import { createIntentBus } from "intentx-runtime"
172
+
173
+ const bus = createIntentBus()
174
+
175
+ useLogic(logic, {
176
+ bus
177
+ })
178
+ ```
179
+
180
+ ---
181
+
182
+ ## 🧩 Context API
183
+
184
+ Provide logic via Solid context:
185
+
186
+ ``` ts
187
+ import { setLogicContext, useLogicContext } from "intentx-solid"
188
+ import { counterLogic } from "./counter.logic"
189
+ ```
190
+
191
+ Provider:
192
+
193
+ ``` tsx
194
+ const { Provider } = setLogicContext(
195
+ "counter",
196
+ counterLogic
197
+ )
198
+
199
+ export default function App() {
200
+ return (
201
+ <Provider>
202
+ <Child />
203
+ </Provider>
204
+ )
205
+ }
206
+ ```
207
+
208
+ Consume:
209
+
210
+ ``` ts
211
+ const counter = useLogicContext("counter")
212
+ ```
213
+
214
+ ---
215
+
216
+ ## 🌍 SSR
217
+
218
+ - Runtime created during SSR
219
+ - Deterministic snapshot
220
+ - Hydration-safe
221
+ - No client-only hacks
222
+ - Server snapshot serializable
223
+ - Client rehydrates from deterministic state
224
+
225
+ Works with:
226
+
227
+ - SolidStart
228
+ - Node SSR
229
+ - Edge runtimes
230
+
231
+ ---
232
+
233
+ ## πŸ” Comparison
234
+
235
+ | intentx-solid | Solid |
236
+ | ------------------- | ----------------------- |
237
+ | Intent-driven logic | Fine-grained reactivity |
238
+ | Deterministic state | Reactive DOM updates |
239
+ | Computed graph | Dependency tracking |
240
+ | Effects & async | Declarative components |
241
+
242
+
243
+ - UI consumes state.
244
+ - Logic lives outside components.
245
+
246
+ ---
247
+
248
+ ## 🎯 Philosophy
249
+
250
+ Solid handles rendering.
251
+
252
+ intentx handles intent and state orchestration.
253
+
254
+ Together:
255
+
256
+ > Predictable business logic
257
+ > Ultra-fast fine-grained UI
258
+
259
+ ---
260
+
261
+ ## πŸ“œ License
262
+
263
+ MIT
@@ -0,0 +1 @@
1
+ "use strict";var t=require("solid-js/store"),e=require("solid-js"),s="undefined"!=typeof document?document.currentScript:null;let n=0;function o(t){return Symbol(null!=t?t:"scope-"+ ++n)}const i={activeNode:null,nodes:new Set};let r=0;function c(t){const e={id:++r,type:t,deps:new Set};return i.nodes.add(e),e}function a(t,e){t.deps.add(e)}const d="undefined"==typeof globalThis||void 0===globalThis.__DEV__||globalThis.__DEV__,h={high:new Set,normal:new Set,low:new Set};let u=!1;function l(){u=!0;for(const t of["high","normal","low"])for(const e of h[t])h[t].delete(e),e();u=!1}function f(t,e="normal"){h[e].add(t),u||queueMicrotask(l)}const p=function(){const t={activeEffect:null,activeDeps:null},e=function(t,e){return function(s){let n=s;const o=new Set,r=d?c("signal"):null,h=()=>{var e;const s=t.activeEffect;if(s&&(o.add(s),null===(e=t.activeDeps)||void 0===e||e.add(o)),d&&r){const t=i.activeNode;t&&a(t,r)}return n};return h.set=(s,i="normal")=>{Object.is(s,n)||(n=s,o.forEach(s=>{s!==t.activeEffect&&e(s,i)}))},h.subscribe=t=>(o.add(t),()=>o.delete(t)),h}}(t,f),s=function(t,e){return function(s){let n,o=!0;const r=new Set,h=new Set,u=d?c("computed"):null,l=()=>{o||(o=!0,r.forEach(t=>e(t,"normal")))};return()=>{var e;const c=t.activeEffect;if(c&&(r.add(c),null===(e=t.activeDeps)||void 0===e||e.add(r)),o){for(const t of h)t.delete(l);h.clear();const e=t.activeEffect,r=t.activeDeps,c=d?i.activeNode:null;t.activeEffect=l,t.activeDeps=h,d&&u&&(i.activeNode=u);try{n=s(),o=!1}finally{t.activeEffect=e,t.activeDeps=r,d&&(i.activeNode=c)}}if(d&&u){const t=i.activeNode;t&&a(t,u)}return n}}}(t,f),n=function(t,e){return function(s,n="normal"){let o=!1;const r=new Set,a=d?c("effect"):null,h=()=>{if(o)return;for(const t of r)t.delete(h);r.clear();const e=d?i.activeNode:null;try{t.activeEffect=h,t.activeDeps=r,d&&a&&(i.activeNode=a),s()}finally{t.activeEffect=null,t.activeDeps=null,d&&(i.activeNode=e)}};return e(h,n),()=>{o=!0;for(const t of r)t.delete(h);r.clear()}}}(t,f);return{signal:e,createComputed:s,reactiveEffect:n,context:t}}(),m=p.signal,y=p.reactiveEffect;o("default");const g=function(t){const e=function(t){return function(e,s){const n=t(e),o=n.set;return n.set=(t,e="normal")=>{const i=n(),r=s?s(t,i):t;o(r,e)},n.update=(t,e="normal")=>{n.set(t(n()),e)},n}}(t);return function(t,s){var n;const o=null!==(n=null==s?void 0:s.equals)&&void 0!==n?n:Object.is;return e(t,(t,e)=>o(t,e)?e:t)}}(m);class b{constructor(){this.handlers={},this.effects={},this.middlewares=[],this.effectModes={},this.use=t=>{this.middlewares.push(t)},this.setEffectMode=(t,e)=>{this.effectModes[t]=e},this.effect=(t,e)=>{var s;((s=this.effects)[t]??(s[t]=[])).push(e)},this.on=(t,e)=>{var s;const n=(s=this.handlers)[t]??(s[t]=[]);return n.length>0?()=>{}:(n.push(e),()=>{const s=this.handlers[t];if(!s)return;const n=s.indexOf(e);0>n||s.splice(n,1),0===s.length&&delete this.handlers[t]})},this.emit=async(t,e)=>{const s=this.handlers[t]??[],n={context:e,effects:this.effects[t]??[],effectMode:this.effectModes[t]??"sequential"},o=this.middlewares.reduceRight((t,e)=>e(t),async t=>{for(const e of s)await e(t.context)});await o(n)},this.clear=()=>{this.handlers={},this.effects={},this.middlewares=[],this.effectModes={}}}}function w(t){return"function"==typeof structuredClone?structuredClone(t):JSON.parse(JSON.stringify(t))}function v(t){if(null===t||"object"!=typeof t)return t;Object.freeze(t);for(const e of Object.keys(t)){const s=t[e];s&&"object"==typeof s&&!Object.isFrozen(s)&&v(s)}return t}const S=void("undefined"==typeof document?require("url").pathToFileURL(__filename):s&&"SCRIPT"===s.tagName.toUpperCase()&&s.src||new URL("index.cjs",document.baseURI)),D="undefined"!=typeof globalThis&&void 0!==globalThis.process?globalThis.process?.env?.NODE_ENV:void 0,E=S?.DEV??(!!D&&"production"!==D);class k{constructor(t,e=o("logic"),s){this.computedAtoms={},this.subs=new Set,this.dirty=!0,this.isComputing=!1,this.isBatching=!1,this.destroyed=!1,this.computedKeys=new Set,this.computedDisposers=new Set,this.intentDisposers=new Set,this.errorHandlers=new Set,this.leadingLocks=new Set,this.throttleMap=new Map,this.destroy=()=>{this.destroyed||(this.destroyed=!0,this.subs.clear(),this.computedDisposers.forEach(t=>t()),this.computedDisposers.clear(),this.intentDisposers.forEach(t=>t()),this.intentDisposers.clear(),this.leadingLocks.clear(),this.throttleMap.clear(),this.errorHandlers.clear(),this.computedKeys.clear(),this.dirty=!0)},this.createStateAtoms=t=>{const e={};for(const s in t)e[s]=g(t[s]);return e},this.buildSnapshot=()=>{const t={};for(const e in this.stateAtoms)t[e]=this.stateAtoms[e]();for(const e in this.computedAtoms)t[e]=this.computedAtoms[e]();return E?v(t):t},this.markDirty=()=>{this.destroyed||this.isBatching||(this.dirty=!0,this.subs.forEach(t=>t()))},this.createReactiveState=()=>new Proxy({},{get:(t,e)=>{const s=this.stateAtoms[e];return s?s():void 0}}),this.getSnapshot=()=>this.destroyed?this.snapshotCache??this.buildSnapshot():(this.dirty&&(this.snapshotCache=this.buildSnapshot(),this.dirty=!1),this.snapshotCache),this.subscribe=t=>this.destroyed?()=>{}:(this.subs.add(t),()=>this.subs.delete(t)),this.batch=t=>{if(!this.destroyed){this.isBatching=!0;try{t()}finally{this.isBatching=!1,this.markDirty()}}},this.onError=t=>(this.errorHandlers.add(t),()=>this.errorHandlers.delete(t)),this.getComputedKey=t=>this.computedAtoms[t](),this.getComputed=()=>{const t=this.getSnapshot(),e={};return this.computedKeys.forEach(s=>{e[s]=t[s]}),e},this.setStateInternal=t=>{const e={};for(const t in this.stateAtoms)e[t]=this.stateAtoms[t]();t(e);for(const t in this.stateAtoms)e[t]!==this.stateAtoms[t]()&&this.stateAtoms[t].set(e[t])},this.onIntent=(t,e)=>{const s=this.bus.on(t,e);return this.intentDisposers.add(s),()=>{s(),this.intentDisposers.delete(s)}},this.once=(t,e)=>{const s=this.onIntent(t,async t=>{s(),await e(t)})},this.takeLeading=(t,e)=>{this.onIntent(t,async s=>{if(!this.leadingLocks.has(t)){this.leadingLocks.add(t);try{await e(s)}finally{this.leadingLocks.delete(t)}}})},this.throttle=(t,e,s)=>{this.onIntent(t,async n=>{const o=Date.now();o-(this.throttleMap.get(t)??0)<e||(this.throttleMap.set(t,o),await s(n))})},this.useEffect=(t,e)=>{this.bus.effect(t,e)},this.emit=async(t,e)=>{if(this.destroyed)return;const s=new AbortController;try{await this.bus.emit(t,{payload:e,scope:this.scope,signal:s.signal,state:this.getSnapshot,setState:this.setStateInternal,emit:this.emit})}catch(s){this.errorHandlers.forEach(n=>n(s,{type:t,payload:e}))}},this.attachComputed=(t,e)=>{const s=g(void 0),n=this.createReactiveState();this.computedAtoms[t]=s,this.computedKeys.add(t);const o=()=>{this.destroyed||(this.isComputing=!0,s.set(e({state:n})),this.isComputing=!1)},i=y(o);this.computedDisposers.add(i),o();const r=s.subscribe(this.markDirty);this.computedDisposers.add(r)},this.scope=e,this.stateAtoms=this.createStateAtoms(t);for(const t in this.stateAtoms){const e=this.stateAtoms[t].subscribe(this.markDirty);this.computedDisposers.add(e)}s?this.bus=s:(this.bus=new b,this.bus.use(function(){const t=new Map,e=new Map;return s=>async n=>{await s(n);const{effects:o,effectMode:i,context:r}=n;if(!o.length)return;const c=o.map(s=>()=>(async s=>{const n=s.id;if("takeLatest"===s.strategy){t.get(n)?.abort();const e=new AbortController;return t.set(n,e),s.handler({...r,signal:e.signal})}return"debounce"===s.strategy?(clearTimeout(e.get(n)),new Promise(t=>{e.set(n,setTimeout(async()=>{await s.handler(r),t()},s.wait))})):s.handler(r)})(s));switch(i){case"parallel":await Promise.all(c.map(t=>t()));break;case"race":await Promise.race(c.map(t=>t()));break;case"allSettled":await Promise.allSettled(c.map(t=>t()));break;default:for(const t of c){const e=t();await e}}}}())),E&&(this.__debugId="runtime-"+Math.random().toString(36).slice(2))}get state(){return this.getSnapshot()}get computed(){const t={};return this.computedKeys.forEach(e=>{t[e]=this.computedAtoms[e]()}),t}}const C=()=>new b;let A=null;const x=new Map;function M(){return A||(A=C()),A}function L(t){return t?(x.has(t)||x.set(t,C()),x.get(t)):M()}const _="undefined"!=typeof window;function N(s,n){const i="string"==typeof n?.scope?o(n.scope):n?.scope,r=n?.bus??(n?.sharedBus?L("string"==typeof n?.scope?n.scope:void 0):void 0),c=r?s.create(i,r):s.create(i),[a,d]=t.createStore(c.getSnapshot());let h=()=>{};return _&&(h=c.subscribe(()=>{d(t.reconcile(c.getSnapshot()))}),e.onCleanup(()=>{h(),c.destroy?.()})),{runtime:c,store:a,state:a,actions:c.actions,emit:c.emit.bind(c)}}const j=e.createContext({});exports.createIntentBus=C,exports.createLogic=function(t){return{name:t.name,createShareBus(t,e){return this.create(t,e)},createIsolated(t){return this.create(t,void 0)},create(e,s){const n=new k(w(t.state),e,s);if(E&&!n.devtools){const e=function(t,e){const s=function(){let t=0,e=[];return{get records(){return e.slice()},record:function(s){e.push({...s,id:++t,state:w(s.state)})},replay:async function(t,s){const{from:n=0,to:o=1/0,scope:i}=s??{},r=e.filter(t=>!("emit"!==t.type||n>t.id||t.id>o||i&&t.scope!==i));for(const e of r){const s=t(e.intent,e.payload);s instanceof Promise&&await s}},clear:function(){e=[],t=0}}}(),n=Symbol("devtools_wrapped");function o(){const s=e||t.scope;return s?"string"==typeof s?s:s.name??"anonymous":"global"}function i(){return"function"==typeof t.getSnapshot?t.getSnapshot():"function"==typeof t.state?t.state():void 0}return{timeline:s,wrap:function(){if(t[n])return;t[n]=!0;const e=t.emit.bind(t);t.emit=async(t,n)=>{s.record({type:"emit:start",intent:t,payload:n,scope:o(),state:i(),timestamp:Date.now()});try{await Promise.resolve(e(t,n))}catch(e){throw s.record({type:"emit:error",intent:t,payload:n,scope:o(),state:i(),timestamp:Date.now()}),e}s.record({type:"emit:end",intent:t,payload:n,scope:o(),state:i(),timestamp:Date.now()})}}}}(n,t.name??"logic");e.wrap(),n.devtools=e}if(t.computed)for(const e in t.computed)n.attachComputed(e,t.computed[e]);t.intents?.({on:n.onIntent,effect:(t,e)=>n.useEffect(t,e)});const o={};if(t.actions){const e=Object.keys(t.actions);for(const s of e)o[s]=(0,t.actions[s])({emit:n.emit,getState:n.getSnapshot})}return n.actions=o,n}}},exports.effect=function(t){const e={_kind:"effect",id:Symbol("effect"),handler:t,strategy:"default"},s=(t={})=>{const n={...e,...t};return Object.assign(n,{takeLatest:()=>s({strategy:"takeLatest"}),debounce:t=>s({strategy:"debounce",wait:t}),blocking:()=>s({blocking:!0})})};return s()},exports.getGlobalBus=M,exports.getScopedBus=L,exports.setLogicContext=function(t,e,s){const n=N(e,s);return{Provider:function(e){return j.Provider({value:{[t]:n},get children(){return e.children}})},store:n}},exports.useLogic=N,exports.useLogicContext=function(t){const s=e.useContext(j);if(!s||!s[t])throw Error(`Logic "${t}" not found in context`);return s[t]};
@@ -0,0 +1,38 @@
1
+ import { createIntentBus, LogicActions, LogicFactory, Scope } from 'intentx-runtime';
2
+ export { EffectMode, ExtractLogicTypes, IntentContext, LogicActions, LogicFactory, LogicRuntime, createIntentBus, createLogic, effect } from 'intentx-runtime';
3
+ import * as solid_js from 'solid-js';
4
+
5
+ type IntentBus = ReturnType<typeof createIntentBus>;
6
+ declare function getGlobalBus(): IntentBus;
7
+ declare function getScopedBus(scope?: string): IntentBus;
8
+
9
+ type ComputedDef<S> = Record<string, (context: {
10
+ state: Readonly<S>;
11
+ }) => any>;
12
+ type InferComputed<C> = {
13
+ [K in keyof C]: C[K] extends (...args: any) => infer R ? R : never;
14
+ };
15
+ type LogicInstance<S, C, A extends LogicActions> = {
16
+ runtime: any;
17
+ store: Readonly<S & InferComputed<C>>;
18
+ state: Readonly<S & InferComputed<C>>;
19
+ actions: A;
20
+ emit: (...args: any[]) => Promise<void>;
21
+ };
22
+
23
+ declare function useLogic<S extends object, C extends ComputedDef<S>, A extends LogicActions>(logic: LogicFactory<S, C, A>, options?: {
24
+ scope?: Scope | string;
25
+ sharedBus?: boolean;
26
+ bus?: ReturnType<typeof getScopedBus>;
27
+ }): LogicInstance<S, C, A>;
28
+
29
+ declare function setLogicContext<S extends object, C extends ComputedDef<S>, A extends LogicActions>(key: string, logic: LogicFactory<S, C, A>, options?: Parameters<typeof useLogic<S, C, A>>[1]): {
30
+ Provider: (props: {
31
+ children: any;
32
+ }) => solid_js.JSX.Element;
33
+ store: LogicInstance<S, C, A>;
34
+ };
35
+ declare function useLogicContext<T>(key: string): T;
36
+
37
+ export { getGlobalBus, getScopedBus, setLogicContext, useLogic, useLogicContext };
38
+ export type { ComputedDef, InferComputed, IntentBus, LogicInstance };
package/build/index.js ADDED
@@ -0,0 +1 @@
1
+ import{createStore as t,reconcile as e}from"solid-js/store";import{onCleanup as s,createContext as n,useContext as o}from"solid-js";let i=0;function r(t){return Symbol(null!=t?t:"scope-"+ ++i)}const c={activeNode:null,nodes:new Set};let a=0;function h(t){const e={id:++a,type:t,deps:new Set};return c.nodes.add(e),e}function d(t,e){t.deps.add(e)}const u="undefined"==typeof globalThis||void 0===globalThis.__DEV__||globalThis.__DEV__,l={high:new Set,normal:new Set,low:new Set};let f=!1;function p(){f=!0;for(const t of["high","normal","low"])for(const e of l[t])l[t].delete(e),e();f=!1}function m(t,e="normal"){l[e].add(t),f||queueMicrotask(p)}const y=function(){const t={activeEffect:null,activeDeps:null},e=function(t,e){return function(s){let n=s;const o=new Set,i=u?h("signal"):null,r=()=>{var e;const s=t.activeEffect;if(s&&(o.add(s),null===(e=t.activeDeps)||void 0===e||e.add(o)),u&&i){const t=c.activeNode;t&&d(t,i)}return n};return r.set=(s,i="normal")=>{Object.is(s,n)||(n=s,o.forEach(s=>{s!==t.activeEffect&&e(s,i)}))},r.subscribe=t=>(o.add(t),()=>o.delete(t)),r}}(t,m),s=function(t,e){return function(s){let n,o=!0;const i=new Set,r=new Set,a=u?h("computed"):null,l=()=>{o||(o=!0,i.forEach(t=>e(t,"normal")))};return()=>{var e;const h=t.activeEffect;if(h&&(i.add(h),null===(e=t.activeDeps)||void 0===e||e.add(i)),o){for(const t of r)t.delete(l);r.clear();const e=t.activeEffect,i=t.activeDeps,h=u?c.activeNode:null;t.activeEffect=l,t.activeDeps=r,u&&a&&(c.activeNode=a);try{n=s(),o=!1}finally{t.activeEffect=e,t.activeDeps=i,u&&(c.activeNode=h)}}if(u&&a){const t=c.activeNode;t&&d(t,a)}return n}}}(t,m),n=function(t,e){return function(s,n="normal"){let o=!1;const i=new Set,r=u?h("effect"):null,a=()=>{if(o)return;for(const t of i)t.delete(a);i.clear();const e=u?c.activeNode:null;try{t.activeEffect=a,t.activeDeps=i,u&&r&&(c.activeNode=r),s()}finally{t.activeEffect=null,t.activeDeps=null,u&&(c.activeNode=e)}};return e(a,n),()=>{o=!0;for(const t of i)t.delete(a);i.clear()}}}(t,m);return{signal:e,createComputed:s,reactiveEffect:n,context:t}}(),g=y.signal,w=y.reactiveEffect;r("default");const b=function(t){const e=function(t){return function(e,s){const n=t(e),o=n.set;return n.set=(t,e="normal")=>{const i=n(),r=s?s(t,i):t;o(r,e)},n.update=(t,e="normal")=>{n.set(t(n()),e)},n}}(t);return function(t,s){var n;const o=null!==(n=null==s?void 0:s.equals)&&void 0!==n?n:Object.is;return e(t,(t,e)=>o(t,e)?e:t)}}(g);class v{constructor(){this.handlers={},this.effects={},this.middlewares=[],this.effectModes={},this.use=t=>{this.middlewares.push(t)},this.setEffectMode=(t,e)=>{this.effectModes[t]=e},this.effect=(t,e)=>{var s;((s=this.effects)[t]??(s[t]=[])).push(e)},this.on=(t,e)=>{var s;const n=(s=this.handlers)[t]??(s[t]=[]);return n.length>0?()=>{}:(n.push(e),()=>{const s=this.handlers[t];if(!s)return;const n=s.indexOf(e);0>n||s.splice(n,1),0===s.length&&delete this.handlers[t]})},this.emit=async(t,e)=>{const s=this.handlers[t]??[],n={context:e,effects:this.effects[t]??[],effectMode:this.effectModes[t]??"sequential"},o=this.middlewares.reduceRight((t,e)=>e(t),async t=>{for(const e of s)await e(t.context)});await o(n)},this.clear=()=>{this.handlers={},this.effects={},this.middlewares=[],this.effectModes={}}}}function S(t){return"function"==typeof structuredClone?structuredClone(t):JSON.parse(JSON.stringify(t))}function D(t){if(null===t||"object"!=typeof t)return t;Object.freeze(t);for(const e of Object.keys(t)){const s=t[e];s&&"object"==typeof s&&!Object.isFrozen(s)&&D(s)}return t}const E=void 0!==import.meta?import.meta.env:void 0,k="undefined"!=typeof globalThis&&void 0!==globalThis.process?globalThis.process?.env?.NODE_ENV:void 0,A=E?.DEV??(!!k&&"production"!==k);class M{constructor(t,e=r("logic"),s){this.computedAtoms={},this.subs=new Set,this.dirty=!0,this.isComputing=!1,this.isBatching=!1,this.destroyed=!1,this.computedKeys=new Set,this.computedDisposers=new Set,this.intentDisposers=new Set,this.errorHandlers=new Set,this.leadingLocks=new Set,this.throttleMap=new Map,this.destroy=()=>{this.destroyed||(this.destroyed=!0,this.subs.clear(),this.computedDisposers.forEach(t=>t()),this.computedDisposers.clear(),this.intentDisposers.forEach(t=>t()),this.intentDisposers.clear(),this.leadingLocks.clear(),this.throttleMap.clear(),this.errorHandlers.clear(),this.computedKeys.clear(),this.dirty=!0)},this.createStateAtoms=t=>{const e={};for(const s in t)e[s]=b(t[s]);return e},this.buildSnapshot=()=>{const t={};for(const e in this.stateAtoms)t[e]=this.stateAtoms[e]();for(const e in this.computedAtoms)t[e]=this.computedAtoms[e]();return A?D(t):t},this.markDirty=()=>{this.destroyed||this.isBatching||(this.dirty=!0,this.subs.forEach(t=>t()))},this.createReactiveState=()=>new Proxy({},{get:(t,e)=>{const s=this.stateAtoms[e];return s?s():void 0}}),this.getSnapshot=()=>this.destroyed?this.snapshotCache??this.buildSnapshot():(this.dirty&&(this.snapshotCache=this.buildSnapshot(),this.dirty=!1),this.snapshotCache),this.subscribe=t=>this.destroyed?()=>{}:(this.subs.add(t),()=>this.subs.delete(t)),this.batch=t=>{if(!this.destroyed){this.isBatching=!0;try{t()}finally{this.isBatching=!1,this.markDirty()}}},this.onError=t=>(this.errorHandlers.add(t),()=>this.errorHandlers.delete(t)),this.getComputedKey=t=>this.computedAtoms[t](),this.getComputed=()=>{const t=this.getSnapshot(),e={};return this.computedKeys.forEach(s=>{e[s]=t[s]}),e},this.setStateInternal=t=>{const e={};for(const t in this.stateAtoms)e[t]=this.stateAtoms[t]();t(e);for(const t in this.stateAtoms)e[t]!==this.stateAtoms[t]()&&this.stateAtoms[t].set(e[t])},this.onIntent=(t,e)=>{const s=this.bus.on(t,e);return this.intentDisposers.add(s),()=>{s(),this.intentDisposers.delete(s)}},this.once=(t,e)=>{const s=this.onIntent(t,async t=>{s(),await e(t)})},this.takeLeading=(t,e)=>{this.onIntent(t,async s=>{if(!this.leadingLocks.has(t)){this.leadingLocks.add(t);try{await e(s)}finally{this.leadingLocks.delete(t)}}})},this.throttle=(t,e,s)=>{this.onIntent(t,async n=>{const o=Date.now();o-(this.throttleMap.get(t)??0)<e||(this.throttleMap.set(t,o),await s(n))})},this.useEffect=(t,e)=>{this.bus.effect(t,e)},this.emit=async(t,e)=>{if(this.destroyed)return;const s=new AbortController;try{await this.bus.emit(t,{payload:e,scope:this.scope,signal:s.signal,state:this.getSnapshot,setState:this.setStateInternal,emit:this.emit})}catch(s){this.errorHandlers.forEach(n=>n(s,{type:t,payload:e}))}},this.attachComputed=(t,e)=>{const s=b(void 0),n=this.createReactiveState();this.computedAtoms[t]=s,this.computedKeys.add(t);const o=()=>{this.destroyed||(this.isComputing=!0,s.set(e({state:n})),this.isComputing=!1)},i=w(o);this.computedDisposers.add(i),o();const r=s.subscribe(this.markDirty);this.computedDisposers.add(r)},this.scope=e,this.stateAtoms=this.createStateAtoms(t);for(const t in this.stateAtoms){const e=this.stateAtoms[t].subscribe(this.markDirty);this.computedDisposers.add(e)}s?this.bus=s:(this.bus=new v,this.bus.use(function(){const t=new Map,e=new Map;return s=>async n=>{await s(n);const{effects:o,effectMode:i,context:r}=n;if(!o.length)return;const c=o.map(s=>()=>(async s=>{const n=s.id;if("takeLatest"===s.strategy){t.get(n)?.abort();const e=new AbortController;return t.set(n,e),s.handler({...r,signal:e.signal})}return"debounce"===s.strategy?(clearTimeout(e.get(n)),new Promise(t=>{e.set(n,setTimeout(async()=>{await s.handler(r),t()},s.wait))})):s.handler(r)})(s));switch(i){case"parallel":await Promise.all(c.map(t=>t()));break;case"race":await Promise.race(c.map(t=>t()));break;case"allSettled":await Promise.allSettled(c.map(t=>t()));break;default:for(const t of c){const e=t();await e}}}}())),A&&(this.__debugId="runtime-"+Math.random().toString(36).slice(2))}get state(){return this.getSnapshot()}get computed(){const t={};return this.computedKeys.forEach(e=>{t[e]=this.computedAtoms[e]()}),t}}function C(t){const e={_kind:"effect",id:Symbol("effect"),handler:t,strategy:"default"},s=(t={})=>{const n={...e,...t};return Object.assign(n,{takeLatest:()=>s({strategy:"takeLatest"}),debounce:t=>s({strategy:"debounce",wait:t}),blocking:()=>s({blocking:!0})})};return s()}function N(t){return{name:t.name,createShareBus(t,e){return this.create(t,e)},createIsolated(t){return this.create(t,void 0)},create(e,s){const n=new M(S(t.state),e,s);if(A&&!n.devtools){const e=function(t,e){const s=function(){let t=0,e=[];return{get records(){return e.slice()},record:function(s){e.push({...s,id:++t,state:S(s.state)})},replay:async function(t,s){const{from:n=0,to:o=1/0,scope:i}=s??{},r=e.filter(t=>!("emit"!==t.type||n>t.id||t.id>o||i&&t.scope!==i));for(const e of r){const s=t(e.intent,e.payload);s instanceof Promise&&await s}},clear:function(){e=[],t=0}}}(),n=Symbol("devtools_wrapped");function o(){const s=e||t.scope;return s?"string"==typeof s?s:s.name??"anonymous":"global"}function i(){return"function"==typeof t.getSnapshot?t.getSnapshot():"function"==typeof t.state?t.state():void 0}return{timeline:s,wrap:function(){if(t[n])return;t[n]=!0;const e=t.emit.bind(t);t.emit=async(t,n)=>{s.record({type:"emit:start",intent:t,payload:n,scope:o(),state:i(),timestamp:Date.now()});try{await Promise.resolve(e(t,n))}catch(e){throw s.record({type:"emit:error",intent:t,payload:n,scope:o(),state:i(),timestamp:Date.now()}),e}s.record({type:"emit:end",intent:t,payload:n,scope:o(),state:i(),timestamp:Date.now()})}}}}(n,t.name??"logic");e.wrap(),n.devtools=e}if(t.computed)for(const e in t.computed)n.attachComputed(e,t.computed[e]);t.intents?.({on:n.onIntent,effect:(t,e)=>n.useEffect(t,e)});const o={};if(t.actions){const e=Object.keys(t.actions);for(const s of e)o[s]=(0,t.actions[s])({emit:n.emit,getState:n.getSnapshot})}return n.actions=o,n}}}const _=()=>new v;let j=null;const L=new Map;function O(){return j||(j=_()),j}function I(t){return t?(L.has(t)||L.set(t,_()),L.get(t)):O()}const P="undefined"!=typeof window;function x(n,o){const i="string"==typeof o?.scope?r(o.scope):o?.scope,c=o?.bus??(o?.sharedBus?I("string"==typeof o?.scope?o.scope:void 0):void 0),a=c?n.create(i,c):n.create(i),[h,d]=t(a.getSnapshot());let u=()=>{};return P&&(u=a.subscribe(()=>{d(e(a.getSnapshot()))}),s(()=>{u(),a.destroy?.()})),{runtime:a,store:h,state:h,actions:a.actions,emit:a.emit.bind(a)}}const T=n({});function B(t,e,s){const n=x(e,s);return{Provider:function(e){return T.Provider({value:{[t]:n},get children(){return e.children}})},store:n}}function K(t){const e=o(T);if(!e||!e[t])throw Error(`Logic "${t}" not found in context`);return e[t]}export{_ as createIntentBus,N as createLogic,C as effect,O as getGlobalBus,I as getScopedBus,B as setLogicContext,x as useLogic,K as useLogicContext};
@@ -0,0 +1,4 @@
1
+ import { createIntentBus } from "intentx-runtime";
2
+ export type IntentBus = ReturnType<typeof createIntentBus>;
3
+ export declare function getGlobalBus(): IntentBus;
4
+ export declare function getScopedBus(scope?: string): IntentBus;
@@ -0,0 +1,10 @@
1
+ import type { LogicFactory, LogicActions } from "intentx-runtime";
2
+ import { useLogic } from "./useLogic";
3
+ import type { ComputedDef } from "./types";
4
+ export declare function setLogicContext<S extends object, C extends ComputedDef<S>, A extends LogicActions>(key: string, logic: LogicFactory<S, C, A>, options?: Parameters<typeof useLogic<S, C, A>>[1]): {
5
+ Provider: (props: {
6
+ children: any;
7
+ }) => import("solid-js").JSX.Element;
8
+ store: import("./types").LogicInstance<S, C, A>;
9
+ };
10
+ export declare function useLogicContext<T>(key: string): T;
@@ -0,0 +1,4 @@
1
+ export * from "./useLogic";
2
+ export * from "./context";
3
+ export * from "./bus";
4
+ export * from "./types";
@@ -0,0 +1,14 @@
1
+ import type { LogicActions } from "intentx-runtime";
2
+ export type ComputedDef<S> = Record<string, (context: {
3
+ state: Readonly<S>;
4
+ }) => any>;
5
+ export type InferComputed<C> = {
6
+ [K in keyof C]: C[K] extends (...args: any) => infer R ? R : never;
7
+ };
8
+ export type LogicInstance<S, C, A extends LogicActions> = {
9
+ runtime: any;
10
+ store: Readonly<S & InferComputed<C>>;
11
+ state: Readonly<S & InferComputed<C>>;
12
+ actions: A;
13
+ emit: (...args: any[]) => Promise<void>;
14
+ };
@@ -0,0 +1,8 @@
1
+ import type { Scope, LogicFactory, LogicActions } from "intentx-runtime";
2
+ import { getScopedBus } from "./bus";
3
+ import type { ComputedDef, LogicInstance } from "./types";
4
+ export declare function useLogic<S extends object, C extends ComputedDef<S>, A extends LogicActions>(logic: LogicFactory<S, C, A>, options?: {
5
+ scope?: Scope | string;
6
+ sharedBus?: boolean;
7
+ bus?: ReturnType<typeof getScopedBus>;
8
+ }): LogicInstance<S, C, A>;
package/package.json ADDED
@@ -0,0 +1,74 @@
1
+ {
2
+ "name": "intentx-solid",
3
+ "version": "0.0.1",
4
+ "description": "Intent-driven logic adapter for SolidJS. Connects intentx-runtime with Solid's fine-grained reactivity.",
5
+ "type": "module",
6
+ "main": "build/index.cjs",
7
+ "module": "build/index.js",
8
+ "types": "build/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "import": "./build/index.js",
12
+ "require": "./build/index.cjs",
13
+ "types": "./build/index.d.ts"
14
+ }
15
+ },
16
+ "files": [
17
+ "build"
18
+ ],
19
+ "sideEffects": false,
20
+ "license": "MIT",
21
+ "author": "Delpi.Kye",
22
+ "repository": {
23
+ "type": "git",
24
+ "url": "https://github.com/delpikye-v/intentx-solid.git"
25
+ },
26
+ "homepage": "https://github.com/delpikye-v/intentx-solid#readme",
27
+ "bugs": {
28
+ "url": "https://github.com/delpikye-v/intentx-solid/issues"
29
+ },
30
+ "funding": {
31
+ "type": "github",
32
+ "url": "https://github.com/sponsors/delpikye-v"
33
+ },
34
+ "keywords": [
35
+ "solid",
36
+ "solidjs",
37
+ "state",
38
+ "state-management",
39
+ "logic",
40
+ "intent",
41
+ "event-driven",
42
+ "runtime",
43
+ "microfrontend",
44
+ "architecture"
45
+ ],
46
+ "engines": {
47
+ "node": ">=18"
48
+ },
49
+ "peerDependencies": {
50
+ "solid-js": "^1.8.0"
51
+ },
52
+ "dependencies": {
53
+ "intentx-runtime": ">=0.2.2"
54
+ },
55
+ "devDependencies": {
56
+ "@rollup/plugin-commonjs": "^25.0.0",
57
+ "@rollup/plugin-node-resolve": "^15.2.3",
58
+ "@rollup/plugin-terser": "^0.4.4",
59
+ "@rollup/plugin-typescript": "^12.3.0",
60
+ "rollup": "^4.9.6",
61
+ "rollup-plugin-dts": "^6.3.0",
62
+ "rollup-plugin-peer-deps-external": "^2.2.4",
63
+ "rollup-plugin-typescript2": "^0.36.0",
64
+ "rimraf": "^5.0.5",
65
+ "tslib": "^2.6.2",
66
+ "typescript": "^5.3.3",
67
+ "unplugin-solid": "^1.0.0"
68
+ },
69
+ "scripts": {
70
+ "clean": "rimraf build",
71
+ "build": "rollup -c",
72
+ "cb": "npm run clean && npm run build"
73
+ }
74
+ }