@e280/strata 0.2.5 → 0.2.8

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 CHANGED
@@ -1,7 +1,7 @@
1
1
 
2
2
  MIT License
3
3
 
4
- Copyright (c) 2025 Chase Moskal
4
+ Copyright (c) 2026 Chase Moskal
5
5
 
6
6
  Permission is hereby granted, free of charge, to any person obtaining a copy
7
7
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -17,6 +17,7 @@
17
17
  🚦 [**signals**](#signals) — ephemeral view-level state
18
18
  🔮 [**prism**](#prism) — app-level state tree
19
19
  🪄 [**tracker**](#tracker) — reactivity integration hub
20
+ ⚛️ [**react**](#react) — optional bindings for react
20
21
 
21
22
 
22
23
 
@@ -363,6 +364,50 @@ note, the *items* that the tracker tracks can be any object, or symbol.. the tra
363
364
 
364
365
 
365
366
 
367
+ <br/><br/>
368
+
369
+ <a id="react"></a>
370
+
371
+ ## 🍋 react bindings
372
+ > *easy peasy*
373
+
374
+ ### ⚛️ react setup
375
+
376
+ 1. setup your `strata.ts` module
377
+ ```ts
378
+ import * as react from "react"
379
+ import {react as strata} from "@e280/strata"
380
+
381
+ export const {component, useStrata} = strata(react)
382
+ ```
383
+ 1. now you import `component` and `useStrata` from your module
384
+ ```ts
385
+ import {component, useStrata} from "./strata.js"
386
+ ```
387
+
388
+ ### ⚛️ `component` enables fully automatic reactive re-rendering
389
+ ```ts
390
+ const $count = signal(0)
391
+
392
+ export const MyCounter = component(() => {
393
+ const add = () => $count.value++
394
+ return <button onClick={add}>{$count()}</button>
395
+ })
396
+ ```
397
+
398
+ ### ⚛️ `useStrata` for a manual hands-on approach
399
+ ```ts
400
+ const $count = signal(0)
401
+
402
+ export const MyCounter = () => {
403
+ const count = useStrata(() => $count())
404
+ const add = () => $count.value++
405
+ return <button onClick={add}>{count}</button>
406
+ }
407
+ ```
408
+
409
+
410
+
366
411
  <br/><br/>
367
412
 
368
413
  ## 🧑‍💻 strata is by e280
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@e280/strata",
3
- "version": "0.2.5",
3
+ "version": "0.2.8",
4
4
  "description": "state management",
5
5
  "license": "MIT",
6
6
  "author": "Chase Moskal <chasemoskal@gmail.com>",
@@ -30,12 +30,12 @@
30
30
  "_tscw": "tsc -w"
31
31
  },
32
32
  "dependencies": {
33
- "@e280/stz": "^0.2.15"
33
+ "@e280/stz": "^0.2.21"
34
34
  },
35
35
  "devDependencies": {
36
- "@e280/science": "^0.1.4",
37
- "@e280/scute": "^0.1.2",
38
- "@types/node": "^24.10.1",
36
+ "@e280/science": "^0.1.8",
37
+ "@e280/scute": "^0.2.2",
38
+ "@types/node": "^25.3.2",
39
39
  "npm-run-all": "^4.1.5",
40
40
  "typescript": "^5.9.3"
41
41
  },
@@ -0,0 +1,42 @@
1
+
2
+ import {tracker} from "../tracker.js"
3
+
4
+ export function react(react: {
5
+ useState: <X>(x: X) => [value: X, set: (fn: (x: X) => void) => void]
6
+ useEffect: (fn: () => void) => void
7
+ }) {
8
+
9
+ const useStrata = <X>(fn: () => X) => {
10
+ const [, setTick] = react.useState(0)
11
+ const {seen, result} = tracker.observe(fn)
12
+
13
+ react.useEffect(() => {
14
+ const rerender = async() => setTick(tick => tick + 1)
15
+ const stoppers = [...seen].map(item => tracker.subscribe(item, rerender))
16
+ return () => stoppers.forEach(stop => stop())
17
+ })
18
+
19
+ return result
20
+ }
21
+
22
+ const component = <P extends object, R>(render: (props: P) => R) => {
23
+ function c(props: P) {
24
+ const [, setTick] = react.useState(0)
25
+ const {seen, result} = tracker.observe(() => render(props))
26
+
27
+ react.useEffect(() => {
28
+ const rerender = async() => setTick(tick => tick + 1)
29
+ const stoppers = [...seen].map(item => tracker.subscribe(item, rerender))
30
+ return () => stoppers.forEach(stop => stop())
31
+ })
32
+
33
+ return result
34
+ }
35
+
36
+ c.displayName = (render as any).displayName ?? render.name ?? "Component"
37
+ return c
38
+ }
39
+
40
+ return {component, useStrata}
41
+ }
42
+
@@ -1,3 +1,4 @@
1
1
 
2
2
  export * from "./tracker.js"
3
+ export * from "./bindings/react.js"
3
4
 
@@ -0,0 +1,10 @@
1
+ export declare function react(react: {
2
+ useState: <X>(x: X) => [value: X, set: (fn: (x: X) => void) => void];
3
+ useEffect: (fn: () => void) => void;
4
+ }): {
5
+ component: <P extends object, R>(render: (props: P) => R) => {
6
+ (props: P): R;
7
+ displayName: any;
8
+ };
9
+ useStrata: <X>(fn: () => X) => X;
10
+ };
@@ -0,0 +1,29 @@
1
+ import { tracker } from "../tracker.js";
2
+ export function react(react) {
3
+ const useStrata = (fn) => {
4
+ const [, setTick] = react.useState(0);
5
+ const { seen, result } = tracker.observe(fn);
6
+ react.useEffect(() => {
7
+ const rerender = async () => setTick(tick => tick + 1);
8
+ const stoppers = [...seen].map(item => tracker.subscribe(item, rerender));
9
+ return () => stoppers.forEach(stop => stop());
10
+ });
11
+ return result;
12
+ };
13
+ const component = (render) => {
14
+ function c(props) {
15
+ const [, setTick] = react.useState(0);
16
+ const { seen, result } = tracker.observe(() => render(props));
17
+ react.useEffect(() => {
18
+ const rerender = async () => setTick(tick => tick + 1);
19
+ const stoppers = [...seen].map(item => tracker.subscribe(item, rerender));
20
+ return () => stoppers.forEach(stop => stop());
21
+ });
22
+ return result;
23
+ }
24
+ c.displayName = render.displayName ?? render.name ?? "Component";
25
+ return c;
26
+ };
27
+ return { component, useStrata };
28
+ }
29
+ //# sourceMappingURL=react.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"react.js","sourceRoot":"","sources":["../../../s/tracker/bindings/react.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,OAAO,EAAC,MAAM,eAAe,CAAA;AAErC,MAAM,UAAU,KAAK,CAAC,KAGpB;IAED,MAAM,SAAS,GAAG,CAAI,EAAW,EAAE,EAAE;QACpC,MAAM,CAAC,EAAE,OAAO,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAA;QACrC,MAAM,EAAC,IAAI,EAAE,MAAM,EAAC,GAAG,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;QAE1C,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;YACpB,MAAM,QAAQ,GAAG,KAAK,IAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,GAAG,CAAC,CAAC,CAAA;YACrD,MAAM,QAAQ,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAA;YACzE,OAAO,GAAG,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,CAAA;QAC9C,CAAC,CAAC,CAAA;QAEF,OAAO,MAAM,CAAA;IACd,CAAC,CAAA;IAED,MAAM,SAAS,GAAG,CAAsB,MAAuB,EAAE,EAAE;QAClE,SAAS,CAAC,CAAC,KAAQ;YAClB,MAAM,CAAC,EAAE,OAAO,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAA;YACrC,MAAM,EAAC,IAAI,EAAE,MAAM,EAAC,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAA;YAE3D,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;gBACpB,MAAM,QAAQ,GAAG,KAAK,IAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,GAAG,CAAC,CAAC,CAAA;gBACrD,MAAM,QAAQ,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAA;gBACzE,OAAO,GAAG,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,CAAA;YAC9C,CAAC,CAAC,CAAA;YAEF,OAAO,MAAM,CAAA;QACd,CAAC;QAED,CAAC,CAAC,WAAW,GAAI,MAAc,CAAC,WAAW,IAAI,MAAM,CAAC,IAAI,IAAI,WAAW,CAAA;QACzE,OAAO,CAAC,CAAA;IACT,CAAC,CAAA;IAED,OAAO,EAAC,SAAS,EAAE,SAAS,EAAC,CAAA;AAC9B,CAAC"}
@@ -1 +1,2 @@
1
1
  export * from "./tracker.js";
2
+ export * from "./bindings/react.js";
@@ -1,2 +1,3 @@
1
1
  export * from "./tracker.js";
2
+ export * from "./bindings/react.js";
2
3
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../s/tracker/index.ts"],"names":[],"mappings":"AACA,cAAc,cAAc,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../s/tracker/index.ts"],"names":[],"mappings":"AACA,cAAc,cAAc,CAAA;AAC5B,cAAc,qBAAqB,CAAA"}