ustor 0.0.9 → 0.2.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/dist/index.cjs ADDED
@@ -0,0 +1,125 @@
1
+ 'use strict';
2
+
3
+ const api = {};
4
+ const _s = Symbol();
5
+ const cache = new WeakMap();
6
+ const mutators = /^(copyWithin|fill|pop|push|reverse|shift|sort|splice|unshift)$/;
7
+
8
+ const is = (v) => !!v?.[_s];
9
+ const isObject = (v) => {
10
+ const proto = v && Object.getPrototypeOf(v);
11
+ return v != null && (proto === null || proto?.constructor === Object);
12
+ };
13
+ const resolve = (v) => Array.isArray(v) || isObject(v) ? store(v) : v;
14
+
15
+ const arrayStore = (values) => {
16
+ const version = api.signal(0);
17
+ let depth = 0,
18
+ changed = false;
19
+ const track = () => api.get(version);
20
+ const notify = () => {
21
+ changed = false;
22
+ api.set(version, api.get(version) + 1);
23
+ };
24
+ const proxy = new Proxy(values, {
25
+ get: (target, key, receiver) => {
26
+ if (key === _s) return true;
27
+ track();
28
+ const value = Reflect.get(target, key, receiver);
29
+ if (typeof key === "string" && mutators.test(key) && typeof value === "function") {
30
+ return (...args) => {
31
+ depth++;
32
+ try {
33
+ return value.apply(receiver, args);
34
+ } finally {
35
+ if (!--depth && changed) notify();
36
+ }
37
+ };
38
+ }
39
+ return value;
40
+ },
41
+ set: (target, key, value) => {
42
+ const next = resolve(value);
43
+ if (Object.is(target[key], next)) return true;
44
+ if (!Reflect.set(target, key, next)) return false;
45
+ if (depth) changed = true;
46
+ else notify();
47
+ return true;
48
+ },
49
+ deleteProperty: (target, key) => {
50
+ if (!Object.hasOwn(target, key)) return true;
51
+ if (!Reflect.deleteProperty(target, key)) return false;
52
+ if (depth) changed = true;
53
+ else notify();
54
+ return true;
55
+ },
56
+ ownKeys: (target) => {
57
+ track();
58
+ return Reflect.ownKeys(target);
59
+ },
60
+ has: (target, key) => {
61
+ track();
62
+ return Reflect.has(target, key);
63
+ },
64
+ });
65
+ cache.set(values, proxy);
66
+ values.forEach((item, i) => {
67
+ values[i] = resolve(item);
68
+ });
69
+ return proxy;
70
+ };
71
+
72
+ const objectStore = (values, proto) => {
73
+ const state = Object.create(proto === undefined ? Object.getPrototypeOf(values) : proto);
74
+ cache.set(values, state);
75
+ Reflect.ownKeys(values).forEach((key) => {
76
+ const desc = Object.getOwnPropertyDescriptor(values, key),
77
+ accessor = desc.get || desc.set,
78
+ getter = desc.get?.bind(state),
79
+ memoize = getter && api.memo,
80
+ signal = accessor ? undefined : api.is(desc.value) ? desc.value : api.signal(resolve(desc.value));
81
+ let memo;
82
+ const getSignal = () => getter ? (memo ||= memoize(getter)) : signal;
83
+ Object.defineProperty(state, key, {
84
+ get: accessor
85
+ ? getter
86
+ ? () => memoize ? (api.getMemo || api.get)(getSignal()) : getter()
87
+ : undefined
88
+ : () => api.get(signal),
89
+ set: accessor
90
+ ? desc.set?.bind(state)
91
+ : desc.writable === false
92
+ ? undefined
93
+ : (v) => api.set(signal, resolve(v)),
94
+ enumerable: desc.enumerable,
95
+ });
96
+ if (
97
+ (!accessor || memoize) &&
98
+ typeof key === "string" &&
99
+ !key.startsWith("$") &&
100
+ !Object.hasOwn(values, "$" + key)
101
+ ) {
102
+ Object.defineProperty(state, "$" + key, {
103
+ get: getSignal,
104
+ enumerable: false,
105
+ });
106
+ }
107
+ });
108
+ Object.defineProperty(state, _s, { value: true });
109
+ return Object.seal(state);
110
+ };
111
+
112
+ const store = (values, proto) => {
113
+ if (is(values)) return values;
114
+ if (!Array.isArray(values) && !isObject(values)) return values;
115
+ const cached = cache.get(values);
116
+ if (cached) return cached;
117
+ if (!(api.signal && api.get && api.set && api.is)) {
118
+ throw new Error("ustor: configure api.signal, api.get, api.set and api.is");
119
+ }
120
+ return Array.isArray(values) ? arrayStore(values) : objectStore(values, proto);
121
+ };
122
+
123
+ exports.api = api;
124
+ exports.is = is;
125
+ exports.store = store;
package/dist/index.es.js CHANGED
@@ -1,28 +1,121 @@
1
- let api = {},
2
- _s = Symbol("s"),
3
- is = (v) => v[_s],
4
- isObject = (v) => v && v.constructor === Object,
5
- resolve = (v) => Array.isArray(v) ? store(v) : isObject(v) ? Object.seal(store(v)) : v,
6
- store = (values, proto) => {
7
- if ((is(values) && !proto) || !(api.signal && api.get && api.set && api.is)) return values;
8
- if (Array.isArray(values)) values.forEach((item, i) => values[i] = is(item) ? item : store(item));
9
- if (isObject(values)) {
10
- let state = Object.create(proto || Object.getPrototypeOf(values));
11
- Object.entries(Object.getOwnPropertyDescriptors(values)).forEach(
12
- ([key, desc]) => {
13
- let signal = api.is(desc.value) ? desc.value : api.signal(resolve(desc.value)),
14
- memo = desc.get ? (api.memo ? api.memo(desc.get.bind(state)) : desc.get.bind(state)()) : signal;
15
- Object.defineProperty(state, key, {
16
- get: () => desc.get ? memo : api.get(memo),
17
- set: desc.get ? desc.set?.bind(state) : v => api.set(signal, resolve(v)),
18
- enumerable: true,
19
- });
20
- }
21
- );
22
- Object.defineProperty(state, _s, { value: true });
23
- return state;
24
- }
25
- return values;
26
- };
1
+ const api = {};
2
+ const _s = Symbol();
3
+ const cache = new WeakMap();
4
+ const mutators = /^(copyWithin|fill|pop|push|reverse|shift|sort|splice|unshift)$/;
5
+
6
+ const is = (v) => !!v?.[_s];
7
+ const isObject = (v) => {
8
+ const proto = v && Object.getPrototypeOf(v);
9
+ return v != null && (proto === null || proto?.constructor === Object);
10
+ };
11
+ const resolve = (v) => Array.isArray(v) || isObject(v) ? store(v) : v;
12
+
13
+ const arrayStore = (values) => {
14
+ const version = api.signal(0);
15
+ let depth = 0,
16
+ changed = false;
17
+ const track = () => api.get(version);
18
+ const notify = () => {
19
+ changed = false;
20
+ api.set(version, api.get(version) + 1);
21
+ };
22
+ const proxy = new Proxy(values, {
23
+ get: (target, key, receiver) => {
24
+ if (key === _s) return true;
25
+ track();
26
+ const value = Reflect.get(target, key, receiver);
27
+ if (typeof key === "string" && mutators.test(key) && typeof value === "function") {
28
+ return (...args) => {
29
+ depth++;
30
+ try {
31
+ return value.apply(receiver, args);
32
+ } finally {
33
+ if (!--depth && changed) notify();
34
+ }
35
+ };
36
+ }
37
+ return value;
38
+ },
39
+ set: (target, key, value) => {
40
+ const next = resolve(value);
41
+ if (Object.is(target[key], next)) return true;
42
+ if (!Reflect.set(target, key, next)) return false;
43
+ if (depth) changed = true;
44
+ else notify();
45
+ return true;
46
+ },
47
+ deleteProperty: (target, key) => {
48
+ if (!Object.hasOwn(target, key)) return true;
49
+ if (!Reflect.deleteProperty(target, key)) return false;
50
+ if (depth) changed = true;
51
+ else notify();
52
+ return true;
53
+ },
54
+ ownKeys: (target) => {
55
+ track();
56
+ return Reflect.ownKeys(target);
57
+ },
58
+ has: (target, key) => {
59
+ track();
60
+ return Reflect.has(target, key);
61
+ },
62
+ });
63
+ cache.set(values, proxy);
64
+ values.forEach((item, i) => {
65
+ values[i] = resolve(item);
66
+ });
67
+ return proxy;
68
+ };
69
+
70
+ const objectStore = (values, proto) => {
71
+ const state = Object.create(proto === undefined ? Object.getPrototypeOf(values) : proto);
72
+ cache.set(values, state);
73
+ Reflect.ownKeys(values).forEach((key) => {
74
+ const desc = Object.getOwnPropertyDescriptor(values, key),
75
+ accessor = desc.get || desc.set,
76
+ getter = desc.get?.bind(state),
77
+ memoize = getter && api.memo,
78
+ signal = accessor ? undefined : api.is(desc.value) ? desc.value : api.signal(resolve(desc.value));
79
+ let memo;
80
+ const getSignal = () => getter ? (memo ||= memoize(getter)) : signal;
81
+ Object.defineProperty(state, key, {
82
+ get: accessor
83
+ ? getter
84
+ ? () => memoize ? (api.getMemo || api.get)(getSignal()) : getter()
85
+ : undefined
86
+ : () => api.get(signal),
87
+ set: accessor
88
+ ? desc.set?.bind(state)
89
+ : desc.writable === false
90
+ ? undefined
91
+ : (v) => api.set(signal, resolve(v)),
92
+ enumerable: desc.enumerable,
93
+ });
94
+ if (
95
+ (!accessor || memoize) &&
96
+ typeof key === "string" &&
97
+ !key.startsWith("$") &&
98
+ !Object.hasOwn(values, "$" + key)
99
+ ) {
100
+ Object.defineProperty(state, "$" + key, {
101
+ get: getSignal,
102
+ enumerable: false,
103
+ });
104
+ }
105
+ });
106
+ Object.defineProperty(state, _s, { value: true });
107
+ return Object.seal(state);
108
+ };
109
+
110
+ const store = (values, proto) => {
111
+ if (is(values)) return values;
112
+ if (!Array.isArray(values) && !isObject(values)) return values;
113
+ const cached = cache.get(values);
114
+ if (cached) return cached;
115
+ if (!(api.signal && api.get && api.set && api.is)) {
116
+ throw new Error("ustor: configure api.signal, api.get, api.set and api.is");
117
+ }
118
+ return Array.isArray(values) ? arrayStore(values) : objectStore(values, proto);
119
+ };
27
120
 
28
121
  export { api, is, store };
package/dist/index.min.js CHANGED
@@ -1 +1 @@
1
- var ustor=function(e){let t={},r=Symbol("s"),s=e=>e[r],i=e=>e&&e.constructor===Object,a=e=>Array.isArray(e)?n(e):i(e)?Object.seal(n(e)):e,n=(e,o)=>{if(s(e)&&!o||!(t.signal&&t.get&&t.set&&t.is))return e;if(Array.isArray(e)&&e.forEach(((t,r)=>e[r]=s(t)?t:n(t))),i(e)){let s=Object.create(o||Object.getPrototypeOf(e));return Object.entries(Object.getOwnPropertyDescriptors(e)).forEach((([e,r])=>{let i=t.is(r.value)?r.value:t.signal(a(r.value)),n=r.get?t.memo?t.memo(r.get.bind(s)):r.get.bind(s)():i;Object.defineProperty(s,e,{get:()=>r.get?n:t.get(n),set:r.get?r.set?.bind(s):e=>t.set(i,a(e)),enumerable:!0})})),Object.defineProperty(s,r,{value:!0}),s}return e};return e.api=t,e.is=s,e.store=n,e}({});
1
+ var ustor=function(e){const t={},r=Symbol(),n=new WeakMap,s=/^(copyWithin|fill|pop|push|reverse|shift|sort|splice|unshift)$/,o=e=>!!e?.[r],i=e=>{const t=e&&Object.getPrototypeOf(e);return null!=e&&(null===t||t?.constructor===Object)},c=e=>Array.isArray(e)||i(e)?a(e):e,a=(e,a)=>{if(o(e))return e;if(!Array.isArray(e)&&!i(e))return e;const l=n.get(e);if(l)return l;if(!(t.signal&&t.get&&t.set&&t.is))throw new Error("ustor: configure api.signal, api.get, api.set and api.is");return Array.isArray(e)?(e=>{const o=t.signal(0);let i=0,a=!1;const l=()=>t.get(o),u=()=>{a=!1,t.set(o,t.get(o)+1)},f=new Proxy(e,{get:(e,t,n)=>{if(t===r)return!0;l();const o=Reflect.get(e,t,n);return"string"==typeof t&&s.test(t)&&"function"==typeof o?(...e)=>{i++;try{return o.apply(n,e)}finally{! --i&&a&&u()}}:o},set:(e,t,r)=>{const n=c(r);return!!Object.is(e[t],n)||!!Reflect.set(e,t,n)&&(i?a=!0:u(),!0)},deleteProperty:(e,t)=>!Object.hasOwn(e,t)||!!Reflect.deleteProperty(e,t)&&(i?a=!0:u(),!0),ownKeys:e=>(l(),Reflect.ownKeys(e)),has:(e,t)=>(l(),Reflect.has(e,t))});return n.set(e,f),e.forEach(((t,r)=>{e[r]=c(t)})),f})(e):((e,s)=>{const o=Object.create(void 0===s?Object.getPrototypeOf(e):s);return n.set(e,o),Reflect.ownKeys(e).forEach((r=>{const n=Object.getOwnPropertyDescriptor(e,r),s=n.get||n.set,i=n.get?.bind(o),a=i&&t.memo,l=s?void 0:t.is(n.value)?n.value:t.signal(c(n.value));let u;const f=()=>i?u||=a(i):l;Object.defineProperty(o,r,{get:s?i?()=>a?(t.getMemo||t.get)(f()):i():void 0:()=>t.get(l),set:s?n.set?.bind(o):!1===n.writable?void 0:e=>t.set(l,c(e)),enumerable:n.enumerable}),s&&!a||"string"!=typeof r||r.startsWith("$")||Object.hasOwn(e,"$"+r)||Object.defineProperty(o,"$"+r,{get:f,enumerable:!1})})),Object.defineProperty(o,r,{value:!0}),Object.seal(o)})(e,a)};return e.api=t,e.is=o,e.store=a,e}({});
package/dist/index.umd.js CHANGED
@@ -1 +1 @@
1
- !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).ustor={})}(this,(function(e){let t={},r=Symbol("s"),o=e=>e[r],i=e=>e&&e.constructor===Object,n=e=>Array.isArray(e)?s(e):i(e)?Object.seal(s(e)):e,s=(e,f)=>{if(o(e)&&!f||!(t.signal&&t.get&&t.set&&t.is))return e;if(Array.isArray(e)&&e.forEach(((t,r)=>e[r]=o(t)?t:s(t))),i(e)){let o=Object.create(f||Object.getPrototypeOf(e));return Object.entries(Object.getOwnPropertyDescriptors(e)).forEach((([e,r])=>{let i=t.is(r.value)?r.value:t.signal(n(r.value)),s=r.get?t.memo?t.memo(r.get.bind(o)):r.get.bind(o)():i;Object.defineProperty(o,e,{get:()=>r.get?s:t.get(s),set:r.get?r.set?.bind(o):e=>t.set(i,n(e)),enumerable:!0})})),Object.defineProperty(o,r,{value:!0}),o}return e};e.api=t,e.is=o,e.store=s}));
1
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).ustor={})}(this,(function(e){const t={},r=Symbol(),n=new WeakMap,s=/^(copyWithin|fill|pop|push|reverse|shift|sort|splice|unshift)$/,o=e=>!!e?.[r],i=e=>{const t=e&&Object.getPrototypeOf(e);return null!=e&&(null===t||t?.constructor===Object)},c=e=>Array.isArray(e)||i(e)?a(e):e,a=(e,a)=>{if(o(e))return e;if(!Array.isArray(e)&&!i(e))return e;const f=n.get(e);if(f)return f;if(!(t.signal&&t.get&&t.set&&t.is))throw new Error("ustor: configure api.signal, api.get, api.set and api.is");return Array.isArray(e)?(e=>{const o=t.signal(0);let i=0,a=!1;const f=()=>t.get(o),l=()=>{a=!1,t.set(o,t.get(o)+1)},u=new Proxy(e,{get:(e,t,n)=>{if(t===r)return!0;f();const o=Reflect.get(e,t,n);return"string"==typeof t&&s.test(t)&&"function"==typeof o?(...e)=>{i++;try{return o.apply(n,e)}finally{! --i&&a&&l()}}:o},set:(e,t,r)=>{const n=c(r);return!!Object.is(e[t],n)||!!Reflect.set(e,t,n)&&(i?a=!0:l(),!0)},deleteProperty:(e,t)=>!Object.hasOwn(e,t)||!!Reflect.deleteProperty(e,t)&&(i?a=!0:l(),!0),ownKeys:e=>(f(),Reflect.ownKeys(e)),has:(e,t)=>(f(),Reflect.has(e,t))});return n.set(e,u),e.forEach(((t,r)=>{e[r]=c(t)})),u})(e):((e,s)=>{const o=Object.create(void 0===s?Object.getPrototypeOf(e):s);return n.set(e,o),Reflect.ownKeys(e).forEach((r=>{const n=Object.getOwnPropertyDescriptor(e,r),s=n.get||n.set,i=n.get?.bind(o),a=i&&t.memo,f=s?void 0:t.is(n.value)?n.value:t.signal(c(n.value));let l;const u=()=>i?l||=a(i):f;Object.defineProperty(o,r,{get:s?i?()=>a?(t.getMemo||t.get)(u()):i():void 0:()=>t.get(f),set:s?n.set?.bind(o):!1===n.writable?void 0:e=>t.set(f,c(e)),enumerable:n.enumerable}),s&&!a||"string"!=typeof r||r.startsWith("$")||Object.hasOwn(e,"$"+r)||Object.defineProperty(o,"$"+r,{get:u,enumerable:!1})})),Object.defineProperty(o,r,{value:!0}),Object.seal(o)})(e,a)};e.api=t,e.is=o,e.store=a}));
package/dist/react.cjs ADDED
@@ -0,0 +1 @@
1
+ "use strict";var e=require("react");const r={},t=t=>{const c=e.useCallback((e=>{if(!r.effect)throw new Error("ustor/react: configure api.effect with cleanup support");let c=!0;return r.effect((()=>{t(),c?c=!1:e()}))}),[t]);return e.useSyncExternalStore(c,t,t)};exports.useSignal=c=>{const s=e.useCallback((()=>r.get(c)),[c]);return t(s)},exports.useStore=t;
@@ -0,0 +1 @@
1
+ import{useCallback as t,useSyncExternalStore as r}from"react";const e={},o=o=>{const c=t((t=>{if(!e.effect)throw new Error("ustor/react: configure api.effect with cleanup support");let r=!0;return e.effect((()=>{o(),r?r=!1:t()}))}),[o]);return r(c,o,o)},c=r=>{const c=t((()=>e.get(r)),[r]);return o(c)};export{c as useSignal,o as useStore};
package/package.json CHANGED
@@ -1,43 +1,75 @@
1
1
  {
2
2
  "name": "ustor",
3
- "description": "A lightweight reactive store library that provides a powerful reactivity system for managing state, compatible with any UI framework, including Solid.js, and Preact Signals.",
4
- "version": "0.0.9",
3
+ "description": "A tiny, dependency-free reactive store with pluggable signal adapters and optional React hooks.",
4
+ "version": "0.2.0",
5
5
  "type": "module",
6
6
  "source": "./src/index.js",
7
- "main": "./dist/index.js",
8
- "module": "./dist/index.js",
7
+ "types": "./types/index.d.ts",
8
+ "main": "./dist/index.cjs",
9
+ "module": "./dist/index.es.js",
9
10
  "unpkg": "./dist/index.min.js",
10
11
  "umd:main": "./dist/index.umd.js",
12
+ "sideEffects": false,
11
13
  "exports": {
12
- "browser": "./dist/index.es.js",
13
- "umd": "./dist/index.umd.js",
14
- "require": "./dist/index.js",
15
- "import": "./dist/index.es.js",
16
- "default": "./dist/index.es.js"
14
+ ".": {
15
+ "types": "./types/index.d.ts",
16
+ "browser": "./dist/index.es.js",
17
+ "import": "./dist/index.es.js",
18
+ "require": "./dist/index.cjs",
19
+ "default": "./dist/index.es.js"
20
+ },
21
+ "./react": {
22
+ "types": "./types/react.d.ts",
23
+ "import": "./dist/react.es.js",
24
+ "require": "./dist/react.cjs",
25
+ "default": "./dist/react.es.js"
26
+ },
27
+ "./package.json": "./package.json"
17
28
  },
18
29
  "repository": {
19
30
  "type": "git",
20
31
  "url": "git+https://github.com/kethan/ustor.git"
21
32
  },
22
33
  "files": [
23
- "dist"
34
+ "dist",
35
+ "types"
24
36
  ],
25
37
  "scripts": {
26
- "build": "rollup --config rollup.config.js",
27
- "test": "vitest"
38
+ "build": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\" && rollup --config rollup.config.js",
39
+ "test": "npm run build && npm run typecheck && vitest --run && node test.package.cjs",
40
+ "typecheck": "tsc -p tsconfig.json && tsc -p tsconfig.nodenext.json",
41
+ "test:watch": "vitest",
42
+ "test:coverage": "vitest --run --coverage",
43
+ "profile": "node --expose-gc scripts/profile.mjs",
44
+ "profile:smoke": "node --expose-gc scripts/profile.mjs --updates=5000 --array-updates=500 --seconds=0.5 --cycles=500 --sample-ms=100",
45
+ "prepack": "npm run build"
28
46
  },
29
47
  "devDependencies": {
30
- "@preact/signals-core": "^1.8.0",
31
- "@rollup/plugin-terser": "^0.4.4",
48
+ "@preact/signals-core": "^1.14.4",
49
+ "@rollup/plugin-terser": "^1.0.2",
50
+ "@tanstack/store": "^0.11.2",
51
+ "@vitest/coverage-v8": "^5.0.5",
52
+ "@vue/reactivity": "^3.5.44",
53
+ "@webreflection/alien-signals": "^0.4.2",
54
+ "@webreflection/signal": "^2.1.2",
55
+ "@webreflection/signals": "^0.2.8",
56
+ "alien-signals": "^3.2.1",
57
+ "jsdom": "^30.1.3",
58
+ "mobx": "^7.1.1",
59
+ "nanostores": "^1.5.5",
32
60
  "oby": "^15.1.2",
33
- "reactively": "^0.0.1",
34
- "rollup": "^4.24.0",
61
+ "react": "^19.3.1",
62
+ "react-dom": "^19.3.1",
63
+ "rollup": "^4.65.0",
35
64
  "rollup-plugin-bundle-size": "^1.0.3",
65
+ "rxjs": "^7.8.2",
36
66
  "s-js": "^0.4.9",
37
67
  "sinuous": "^0.32.1",
38
- "solid-js": "^1.9.2",
68
+ "solid-js": "^1.9.17",
69
+ "typescript": "^7.0.2",
39
70
  "ulive": "^1.0.7",
40
- "vitest": "^2.1.3"
71
+ "usignal": "^0.10.0",
72
+ "vitest": "^5.0.5"
41
73
  },
42
74
  "keywords": [
43
75
  "ustor",
@@ -53,7 +85,15 @@
53
85
  "reactive"
54
86
  ],
55
87
  "author": "Kethan Surana",
56
- "license": "ISC",
88
+ "license": "MIT",
89
+ "peerDependencies": {
90
+ "react": ">=18"
91
+ },
92
+ "peerDependenciesMeta": {
93
+ "react": {
94
+ "optional": true
95
+ }
96
+ },
57
97
  "bugs": {
58
98
  "url": "https://github.com/kethan/ustor/issues"
59
99
  },
@@ -0,0 +1,30 @@
1
+ export interface SignalApi<Signal = any, Memo = any> {
2
+ signal(value: any): Signal;
3
+ get(signal: Signal): any;
4
+ set(signal: Signal, value: any): void;
5
+ is(value: unknown): boolean;
6
+ memo?(fn: () => any): Memo;
7
+ getMemo?(memo: Memo): any;
8
+ effect?(fn: () => void): () => void;
9
+ [key: string]: unknown;
10
+ }
11
+
12
+ export type SignalAliases<T> = T extends readonly unknown[] ? unknown : {
13
+ readonly [K in keyof T as K extends string
14
+ ? K extends `$${string}` ? never : `$${K}`
15
+ : never]?: any;
16
+ };
17
+
18
+ export type Store<T> = T extends (...args: any[]) => any
19
+ ? T
20
+ : T extends readonly unknown[]
21
+ ? { [K in keyof T]: Store<T[K]> }
22
+ : T extends object
23
+ ? { [K in keyof T]: Store<T[K]> } & SignalAliases<T>
24
+ : T;
25
+
26
+ export declare const api: SignalApi;
27
+
28
+ export declare function is(value: unknown): value is object;
29
+
30
+ export declare function store<T>(values: T, proto?: object | null): Store<T>;
@@ -0,0 +1,17 @@
1
+ export type SignalValue<Signal> = Signal extends { state: readonly (infer Value)[] }
2
+ ? Value
3
+ : Signal extends { value: infer Value }
4
+ ? Value
5
+ : Signal extends { get(): infer Value }
6
+ ? Value
7
+ : Signal extends () => infer Value
8
+ ? Value
9
+ : Signal extends readonly [() => infer Value, ...any[]]
10
+ ? Value
11
+ : unknown;
12
+
13
+ /** Subscribe to a selector that returns a primitive or stable reference. */
14
+ export declare function useStore<Value>(selector: () => Value): Value;
15
+
16
+ /** Subscribe to one underlying signal exposed as state.$property. */
17
+ export declare function useSignal<Signal>(signal: Signal): SignalValue<Signal>;
package/dist/index.js DELETED
@@ -1,32 +0,0 @@
1
- 'use strict';
2
-
3
- let api = {},
4
- _s = Symbol("s"),
5
- is = (v) => v[_s],
6
- isObject = (v) => v && v.constructor === Object,
7
- resolve = (v) => Array.isArray(v) ? store(v) : isObject(v) ? Object.seal(store(v)) : v,
8
- store = (values, proto) => {
9
- if ((is(values) && !proto) || !(api.signal && api.get && api.set && api.is)) return values;
10
- if (Array.isArray(values)) values.forEach((item, i) => values[i] = is(item) ? item : store(item));
11
- if (isObject(values)) {
12
- let state = Object.create(proto || Object.getPrototypeOf(values));
13
- Object.entries(Object.getOwnPropertyDescriptors(values)).forEach(
14
- ([key, desc]) => {
15
- let signal = api.is(desc.value) ? desc.value : api.signal(resolve(desc.value)),
16
- memo = desc.get ? (api.memo ? api.memo(desc.get.bind(state)) : desc.get.bind(state)()) : signal;
17
- Object.defineProperty(state, key, {
18
- get: () => desc.get ? memo : api.get(memo),
19
- set: desc.get ? desc.set?.bind(state) : v => api.set(signal, resolve(v)),
20
- enumerable: true,
21
- });
22
- }
23
- );
24
- Object.defineProperty(state, _s, { value: true });
25
- return state;
26
- }
27
- return values;
28
- };
29
-
30
- exports.api = api;
31
- exports.is = is;
32
- exports.store = store;