@assistant-ui/tap 0.4.3 → 0.4.5

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.
@@ -1 +1 @@
1
- {"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../src/core/env.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,aAAa,SAEU,CAAC"}
1
+ {"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../src/core/env.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,aAAa,SAGa,CAAC"}
package/dist/core/env.js CHANGED
@@ -1,3 +1,4 @@
1
- export const isDevelopment = process.env["NODE_ENV"] === "development" ||
2
- process.env["NODE_ENV"] === "test";
1
+ export const isDevelopment = typeof process !== "undefined" &&
2
+ (process.env["NODE_ENV"] === "development" ||
3
+ process.env["NODE_ENV"] === "test");
3
4
  //# sourceMappingURL=env.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"env.js","sourceRoot":"","sources":["../../src/core/env.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,aAAa,GACxB,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,aAAa;IACzC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,MAAM,CAAC"}
1
+ {"version":3,"file":"env.js","sourceRoot":"","sources":["../../src/core/env.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,aAAa,GACxB,OAAO,OAAO,KAAK,WAAW;IAC9B,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,aAAa;QACxC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,MAAM,CAAC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"tapSubscribableResource.d.ts","sourceRoot":"","sources":["../src/tapSubscribableResource.ts"],"names":[],"mappings":"AAYA,OAAO,EAAgB,eAAe,EAAE,wBAAqB;AAE7D,yBAAiB,uBAAuB,CAAC;IACvC,KAAY,WAAW,GAAG,MAAM,IAAI,CAAC;IAErC,UAAiB,oBAAoB,CAAC,MAAM;QAC1C;;WAEG;QACH,QAAQ,IAAI,MAAM,CAAC;QAEnB;;WAEG;QACH,SAAS,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,WAAW,CAAC;KAC9C;CACF;AAED,eAAO,MAAM,uBAAuB,GAAI,MAAM,EAC5C,SAAS,eAAe,CAAC,MAAM,CAAC,KAC/B,uBAAuB,CAAC,oBAAoB,CAAC,MAAM,CA0DrD,CAAC"}
1
+ {"version":3,"file":"tapSubscribableResource.d.ts","sourceRoot":"","sources":["../src/tapSubscribableResource.ts"],"names":[],"mappings":"AAYA,OAAO,EAAgB,eAAe,EAAE,wBAAqB;AAE7D,yBAAiB,uBAAuB,CAAC;IACvC,KAAY,WAAW,GAAG,MAAM,IAAI,CAAC;IAErC,UAAiB,oBAAoB,CAAC,MAAM;QAC1C;;WAEG;QACH,QAAQ,IAAI,MAAM,CAAC;QAEnB;;WAEG;QACH,SAAS,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,WAAW,CAAC;KAC9C;CACF;AAED,eAAO,MAAM,uBAAuB,GAAI,MAAM,EAC5C,SAAS,eAAe,CAAC,MAAM,CAAC,KAC/B,uBAAuB,CAAC,oBAAoB,CAAC,MAAM,CAoErD,CAAC"}
@@ -6,41 +6,48 @@ import { tapEffect } from "./hooks/tap-effect.js";
6
6
  import { tapEffectEvent } from "./hooks/tap-effect-event.js";
7
7
  import { tapRef } from "./hooks/tap-ref.js";
8
8
  export const tapSubscribableResource = (element) => {
9
- const scheduler = tapConst(() => new UpdateScheduler(() => handleUpdate()), []);
9
+ const scheduler = tapConst(() => new UpdateScheduler(() => {
10
+ lastRenderRef.current = null;
11
+ handleUpdate();
12
+ }), []);
10
13
  const fiber = tapMemo(() => {
11
14
  void element.key;
12
15
  return createResourceFiber(element.type, (callback) => {
13
16
  if (callback()) {
14
- lastRenderRef.current = null;
15
17
  scheduler.markDirty();
16
18
  }
17
19
  });
18
20
  }, [element.type, element.key]);
19
21
  const lastRenderRef = tapRef(null);
20
22
  lastRenderRef.current = renderResourceFiber(fiber, element.props);
23
+ const isMountedRef = tapRef(false);
21
24
  const committedPropsRef = tapRef(element.props);
22
25
  const valueRef = tapRef(lastRenderRef.current.output);
23
26
  const subscribers = tapConst(() => new Set(), []);
24
27
  const handleUpdate = tapEffectEvent(() => {
28
+ if (!isMountedRef.current)
29
+ return; // skip update if not mounted
25
30
  if (lastRenderRef.current === null) {
26
- if (!fiber.isMounted)
27
- return; // skip
28
31
  lastRenderRef.current = renderResourceFiber(fiber, committedPropsRef.current);
29
32
  }
30
33
  if (scheduler.isDirty)
31
34
  return;
32
35
  committedPropsRef.current = lastRenderRef.current.props;
33
36
  commitResourceFiber(fiber, lastRenderRef.current);
34
- if (scheduler.isDirty)
37
+ if (scheduler.isDirty || valueRef.current === lastRenderRef.current.output)
35
38
  return;
36
39
  valueRef.current = lastRenderRef.current.output;
37
40
  subscribers.forEach((callback) => callback());
38
41
  });
39
- tapEffect(() => () => unmountResourceFiber(fiber), [fiber]);
40
42
  tapEffect(() => {
41
- flushResourcesSync(() => {
42
- scheduler.markDirty();
43
- });
43
+ isMountedRef.current = true;
44
+ return () => {
45
+ isMountedRef.current = false;
46
+ unmountResourceFiber(fiber);
47
+ };
48
+ }, [fiber]);
49
+ tapEffect(() => {
50
+ flushResourcesSync(handleUpdate);
44
51
  });
45
52
  return tapMemo(() => ({
46
53
  getValue: () => valueRef.current,
@@ -1 +1 @@
1
- {"version":3,"file":"tapSubscribableResource.js","sourceRoot":"","sources":["../src/tapSubscribableResource.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tapSubscribableResource.js","sourceRoot":"","sources":["../src/tapSubscribableResource.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@assistant-ui/tap",
3
- "version": "0.4.3",
3
+ "version": "0.4.5",
4
4
  "description": "Zero-dependency reactive state management inspired by React hooks",
5
5
  "keywords": [
6
6
  "state-management",
@@ -48,8 +48,8 @@
48
48
  "devDependencies": {
49
49
  "@testing-library/dom": "^10.4.1",
50
50
  "@testing-library/react": "^16.3.2",
51
- "@types/react": "^19.2.10",
52
- "@types/node": "^25.2.0",
51
+ "@types/react": "^19.2.13",
52
+ "@types/node": "^25.2.1",
53
53
  "@types/react-dom": "^19.2.3",
54
54
  "@vitest/ui": "^4.0.18",
55
55
  "react": "19.2.4",
package/src/core/env.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  export const isDevelopment =
2
- process.env["NODE_ENV"] === "development" ||
3
- process.env["NODE_ENV"] === "test";
2
+ typeof process !== "undefined" &&
3
+ (process.env["NODE_ENV"] === "development" ||
4
+ process.env["NODE_ENV"] === "test");
@@ -32,7 +32,11 @@ export const tapSubscribableResource = <TState>(
32
32
  element: ResourceElement<TState>,
33
33
  ): tapSubscribableResource.SubscribableResource<TState> => {
34
34
  const scheduler = tapConst(
35
- () => new UpdateScheduler(() => handleUpdate()),
35
+ () =>
36
+ new UpdateScheduler(() => {
37
+ lastRenderRef.current = null;
38
+ handleUpdate();
39
+ }),
36
40
  [],
37
41
  );
38
42
  const fiber = tapMemo(() => {
@@ -40,7 +44,6 @@ export const tapSubscribableResource = <TState>(
40
44
 
41
45
  return createResourceFiber(element.type, (callback) => {
42
46
  if (callback()) {
43
- lastRenderRef.current = null;
44
47
  scheduler.markDirty();
45
48
  }
46
49
  });
@@ -49,13 +52,14 @@ export const tapSubscribableResource = <TState>(
49
52
  const lastRenderRef = tapRef<RenderResult | null>(null);
50
53
  lastRenderRef.current = renderResourceFiber(fiber, element.props);
51
54
 
55
+ const isMountedRef = tapRef(false);
52
56
  const committedPropsRef = tapRef(element.props);
53
57
  const valueRef = tapRef<TState>(lastRenderRef.current.output);
54
58
  const subscribers = tapConst(() => new Set<() => void>(), []);
55
59
  const handleUpdate = tapEffectEvent(() => {
56
- if (lastRenderRef.current === null) {
57
- if (!fiber.isMounted) return; // skip
60
+ if (!isMountedRef.current) return; // skip update if not mounted
58
61
 
62
+ if (lastRenderRef.current === null) {
59
63
  lastRenderRef.current = renderResourceFiber(
60
64
  fiber,
61
65
  committedPropsRef.current,
@@ -66,16 +70,22 @@ export const tapSubscribableResource = <TState>(
66
70
  committedPropsRef.current = lastRenderRef.current.props;
67
71
  commitResourceFiber(fiber, lastRenderRef.current);
68
72
 
69
- if (scheduler.isDirty) return;
73
+ if (scheduler.isDirty || valueRef.current === lastRenderRef.current.output)
74
+ return;
70
75
  valueRef.current = lastRenderRef.current.output;
71
76
  subscribers.forEach((callback) => callback());
72
77
  });
73
78
 
74
- tapEffect(() => () => unmountResourceFiber(fiber), [fiber]);
75
79
  tapEffect(() => {
76
- flushResourcesSync(() => {
77
- scheduler.markDirty();
78
- });
80
+ isMountedRef.current = true;
81
+ return () => {
82
+ isMountedRef.current = false;
83
+ unmountResourceFiber(fiber);
84
+ };
85
+ }, [fiber]);
86
+
87
+ tapEffect(() => {
88
+ flushResourcesSync(handleUpdate);
79
89
  });
80
90
 
81
91
  return tapMemo(