flexium
Version:
A lightweight, signals-based UI framework with cross-platform renderers
1 lines • 5.56 kB
Source Map (JSON)
{"version":3,"sources":["../src/store/store.ts"],"names":["SIGNALS","getSignal","target","prop","value","signals","s","signal","proxyTraps","receiver","_target","_prop","_value","_receiver","createStore","initialState","state","args","batch","current","i","rawKey","key","newVal","updateValue","newValue"],"mappings":"uCAGA,IAAMA,CAAAA,CAAU,OAAO,eAAe,CAAA,CAStC,SAASC,CAAAA,CAAUC,CAAAA,CAAmBC,CAAAA,CAAuBC,CAAAA,CAAyB,CAClF,IAAIC,EAAUH,CAAAA,CAAOF,CAAO,CAAA,CACvBK,CAAAA,GACDA,CAAAA,CAAU,IAAI,IACd,MAAA,CAAO,cAAA,CAAeH,CAAAA,CAAQF,CAAAA,CAAS,CAAE,KAAA,CAAOK,EAAS,UAAA,CAAY,KAAM,CAAC,CAAA,CAAA,CAEhF,IAAIC,CAAAA,CAAID,EAAQ,GAAA,CAAIF,CAAI,CAAA,CACxB,OAAKG,CAAAA,GACDA,CAAAA,CAAIC,EAAOH,CAAK,CAAA,CAChBC,CAAAA,CAAQ,GAAA,CAAIF,CAAAA,CAAMG,CAAC,GAEhBA,CACX,CAEA,IAAME,CAAAA,CAAgC,CAClC,GAAA,CAAIN,EAAQC,CAAAA,CAAMM,CAAAA,CAAU,CACxB,GAAIN,CAAAA,GAASH,CAAAA,CAAS,OAAOE,CAAAA,CAAOF,CAAO,CAAA,CAE3C,IAAMI,CAAAA,CAAQ,OAAA,CAAQ,IAAIF,CAAAA,CAAQC,CAAAA,CAAMM,CAAQ,CAAA,CAGhD,OAAI,OAAON,GAAS,QAAA,CAAiBC,CAAAA,EAG3BH,CAAAA,CAAUC,CAAAA,CAAQC,CAAAA,CAAMC,CAAK,EACrC,KAAA,CAGEA,CAAAA,EAAS,OAAOA,CAAAA,EAAU,QAAA,CACnB,IAAI,MAAMA,CAAAA,CAAOI,CAAU,CAAA,CAG/BJ,CAAAA,CACX,CAAA,CAEA,GAAA,CAAIM,EAASC,CAAAA,CAAOC,CAAAA,CAAQC,CAAAA,CAAW,CAEnC,OAAA,OAAA,CAAQ,IAAA,CAAK,qDAAqD,CAAA,CAC3D,IACX,CACJ,CAAA,CAEO,SAASC,CAAAA,CAA8BC,EAAwC,CAGlF,IAAMC,IAAQ,IAAA,CAAK,KAAA,CAAM,KAAK,SAAA,CAAUD,CAAY,CAAC,CAAA,CA0BrD,OAAO,CAxBO,IAAI,KAAA,CAAMC,GAAAA,CAAOR,CAAU,CAAA,CAExB,CAAA,GAAIS,CAAAA,GAAgB,CACjCC,CAAAA,CAAM,IAAM,CACR,IAAIC,CAAAA,CAAUH,GAAAA,CACd,QAASI,CAAAA,CAAI,CAAA,CAAGA,CAAAA,CAAIH,CAAAA,CAAK,MAAA,CAAS,CAAA,CAAGG,IAAK,CACtC,IAAMC,CAAAA,CAASJ,CAAAA,CAAKG,CAAC,CAAA,CAIfE,EAAM,OAAOD,CAAAA,EAAW,QAAA,CAAWA,CAAAA,CAAS,MAAA,CAAOA,CAAM,EAE/D,GAAID,CAAAA,GAAMH,CAAAA,CAAK,MAAA,CAAS,CAAA,CAAG,CAEvB,IAAMM,CAAAA,CAASN,CAAAA,CAAKG,CAAAA,CAAI,CAAC,CAAA,CACzBI,CAAAA,CAAYL,EAASG,CAAAA,CAAeC,CAAM,EAC9C,CAAA,KAEIJ,CAAAA,CAAUA,CAAAA,CAAQG,CAAG,EAE7B,CACJ,CAAC,EACL,CAEuB,CAC3B,CAEA,SAASE,CAAAA,CAAYtB,CAAAA,CAAmBC,CAAAA,CAAuBsB,CAAAA,CAAe,CAG1E,GAFiBvB,CAAAA,CAAOC,CAAW,CAAA,GAElBsB,CAAAA,CAAU,CACvBvB,CAAAA,CAAOC,CAAW,CAAA,CAAIsB,CAAAA,CAGtB,IAAMpB,CAAAA,CAAUH,CAAAA,CAAOF,CAAO,EAC1BK,CAAAA,EAAWA,CAAAA,CAAQ,GAAA,CAAIF,CAAI,CAAA,GAC3BE,CAAAA,CAAQ,IAAIF,CAAI,CAAA,CAAG,KAAA,CAAQsB,CAAAA,EAEnC,CACJ","file":"chunk-62ZYILPI.mjs","sourcesContent":["import { signal, batch, Signal } from '../core/signal';\n\n// Internal symbol to store signals on objects\nconst SIGNALS = Symbol('store-signals');\n\ntype StoreNode = {\n [SIGNALS]?: Map<string | symbol, Signal<any>>;\n [key: string]: any;\n};\n\nexport type SetStoreFunction = (...args: any[]) => void;\n\nfunction getSignal(target: StoreNode, prop: string | symbol, value: any): Signal<any> {\n let signals = target[SIGNALS];\n if (!signals) {\n signals = new Map();\n Object.defineProperty(target, SIGNALS, { value: signals, enumerable: false });\n }\n let s = signals.get(prop);\n if (!s) {\n s = signal(value);\n signals.set(prop, s);\n }\n return s;\n}\n\nconst proxyTraps: ProxyHandler<any> = {\n get(target, prop, receiver) {\n if (prop === SIGNALS) return target[SIGNALS];\n\n const value = Reflect.get(target, prop, receiver);\n\n // If it's a symbol or prototype access, just return\n if (typeof prop === 'symbol') return value;\n\n // Track dependency\n const s = getSignal(target, prop, value);\n s.value; // Access to track\n\n // If it's an object, return a proxy to it (lazy proxying)\n if (value && typeof value === 'object') {\n return new Proxy(value, proxyTraps);\n }\n\n return value;\n },\n\n set(_target, _prop, _value, _receiver) {\n // Stores are read-only via direct assignment\n console.warn('Cannot mutate store directly. Use setStore instead.');\n return true;\n }\n};\n\nexport function createStore<T extends object>(initialState: T): [T, SetStoreFunction] {\n // Deep clone initial state to avoid mutation of original object\n // For simplicity in this MVP, we assume JSON-serializable or simple objects\n const state = JSON.parse(JSON.stringify(initialState));\n\n const store = new Proxy(state, proxyTraps);\n\n const setStore = (...args: any[]) => {\n batch(() => {\n let current = state;\n for (let i = 0; i < args.length - 1; i++) {\n const rawKey = args[i];\n // Proxy traps receive string keys, so we must convert numbers to strings\n // to ensure we access the same Signal in the Map.\n // Symbols should be kept as is.\n const key = typeof rawKey === 'symbol' ? rawKey : String(rawKey);\n \n if (i === args.length - 2) {\n // Last key, update value\n const newVal = args[i + 1];\n updateValue(current, key as string, newVal);\n } else {\n // Navigate down\n current = current[key];\n }\n }\n });\n };\n\n return [store, setStore];\n}\n\nfunction updateValue(target: StoreNode, prop: string | symbol, newValue: any) {\n const oldValue = target[prop as any];\n\n if (oldValue !== newValue) {\n target[prop as any] = newValue;\n\n // Trigger signal update\n const signals = target[SIGNALS];\n if (signals && signals.has(prop)) {\n signals.get(prop)!.value = newValue;\n }\n }\n}\n"]}