rask-ui 0.23.0 → 0.24.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.
Files changed (115) hide show
  1. package/dist/compiler.d.ts +3 -1
  2. package/dist/compiler.d.ts.map +1 -1
  3. package/dist/compiler.js +7 -1
  4. package/dist/component.d.ts +4 -18
  5. package/dist/component.d.ts.map +1 -1
  6. package/dist/component.js +19 -78
  7. package/dist/createComputed.d.ts +4 -0
  8. package/dist/createComputed.d.ts.map +1 -0
  9. package/dist/createComputed.js +69 -0
  10. package/dist/createEffect.d.ts +2 -0
  11. package/dist/createEffect.d.ts.map +1 -0
  12. package/dist/createEffect.js +29 -0
  13. package/dist/createRouter.d.ts +8 -0
  14. package/dist/createRouter.d.ts.map +1 -0
  15. package/dist/createRouter.js +27 -0
  16. package/dist/createState.d.ts +2 -0
  17. package/dist/createState.d.ts.map +1 -1
  18. package/dist/createState.js +40 -5
  19. package/dist/createTask.d.ts +31 -0
  20. package/dist/createTask.d.ts.map +1 -0
  21. package/dist/createTask.js +79 -0
  22. package/dist/createView.d.ts +18 -44
  23. package/dist/createView.d.ts.map +1 -1
  24. package/dist/createView.js +57 -48
  25. package/dist/error.d.ts +3 -14
  26. package/dist/error.d.ts.map +1 -1
  27. package/dist/error.js +14 -15
  28. package/dist/index.d.ts +1 -1
  29. package/dist/index.d.ts.map +1 -1
  30. package/dist/index.js +1 -1
  31. package/dist/jsx.d.ts +10 -256
  32. package/dist/observation.d.ts +1 -1
  33. package/dist/observation.d.ts.map +1 -1
  34. package/dist/patchInferno.d.ts +6 -0
  35. package/dist/patchInferno.d.ts.map +1 -0
  36. package/dist/patchInferno.js +53 -0
  37. package/dist/plugin.d.ts +1 -1
  38. package/dist/plugin.d.ts.map +1 -1
  39. package/dist/plugin.js +14 -26
  40. package/dist/scheduler.d.ts +4 -0
  41. package/dist/scheduler.d.ts.map +1 -0
  42. package/dist/scheduler.js +107 -0
  43. package/dist/tests/batch.test.d.ts +2 -0
  44. package/dist/tests/batch.test.d.ts.map +1 -0
  45. package/dist/tests/batch.test.js +244 -0
  46. package/dist/tests/createComputed.test.d.ts +2 -0
  47. package/dist/tests/createComputed.test.d.ts.map +1 -0
  48. package/dist/tests/createComputed.test.js +257 -0
  49. package/dist/tests/createContext.test.d.ts +2 -0
  50. package/dist/tests/createContext.test.d.ts.map +1 -0
  51. package/dist/tests/createContext.test.js +136 -0
  52. package/dist/tests/createEffect.test.d.ts +2 -0
  53. package/dist/tests/createEffect.test.d.ts.map +1 -0
  54. package/dist/tests/createEffect.test.js +467 -0
  55. package/dist/tests/createState.test.d.ts.map +1 -0
  56. package/dist/tests/createState.test.js +144 -0
  57. package/dist/tests/createTask.test.d.ts +2 -0
  58. package/dist/tests/createTask.test.d.ts.map +1 -0
  59. package/dist/tests/createTask.test.js +322 -0
  60. package/dist/tests/createView.test.d.ts.map +1 -0
  61. package/dist/{createView.test.js → tests/createView.test.js} +40 -40
  62. package/dist/tests/error.test.d.ts +2 -0
  63. package/dist/tests/error.test.d.ts.map +1 -0
  64. package/dist/tests/error.test.js +168 -0
  65. package/dist/tests/observation.test.d.ts.map +1 -0
  66. package/dist/tests/observation.test.js +341 -0
  67. package/dist/useComputed.d.ts +5 -0
  68. package/dist/useComputed.d.ts.map +1 -0
  69. package/dist/useComputed.js +69 -0
  70. package/dist/useQuery.d.ts +25 -0
  71. package/dist/useQuery.d.ts.map +1 -0
  72. package/dist/useQuery.js +25 -0
  73. package/dist/useSuspendAsync.d.ts +18 -0
  74. package/dist/useSuspendAsync.d.ts.map +1 -0
  75. package/dist/useSuspendAsync.js +37 -0
  76. package/dist/useTask.d.ts +25 -0
  77. package/dist/useTask.d.ts.map +1 -0
  78. package/dist/useTask.js +70 -0
  79. package/package.json +1 -1
  80. package/swc-plugin/target/wasm32-wasip1/release/swc_plugin_rask_component.wasm +0 -0
  81. package/dist/asyncState.d.ts +0 -16
  82. package/dist/asyncState.d.ts.map +0 -1
  83. package/dist/asyncState.js +0 -24
  84. package/dist/context.d.ts +0 -5
  85. package/dist/context.d.ts.map +0 -1
  86. package/dist/context.js +0 -29
  87. package/dist/createAsync.test.d.ts +0 -2
  88. package/dist/createAsync.test.d.ts.map +0 -1
  89. package/dist/createAsync.test.js +0 -110
  90. package/dist/createMutation.test.d.ts +0 -2
  91. package/dist/createMutation.test.d.ts.map +0 -1
  92. package/dist/createMutation.test.js +0 -168
  93. package/dist/createQuery.test.d.ts +0 -2
  94. package/dist/createQuery.test.d.ts.map +0 -1
  95. package/dist/createQuery.test.js +0 -156
  96. package/dist/createRef.d.ts +0 -6
  97. package/dist/createRef.d.ts.map +0 -1
  98. package/dist/createRef.js +0 -8
  99. package/dist/createState.test.d.ts.map +0 -1
  100. package/dist/createState.test.js +0 -111
  101. package/dist/createView.test.d.ts.map +0 -1
  102. package/dist/observation.test.d.ts.map +0 -1
  103. package/dist/observation.test.js +0 -150
  104. package/dist/suspense.d.ts +0 -25
  105. package/dist/suspense.d.ts.map +0 -1
  106. package/dist/suspense.js +0 -97
  107. package/dist/test-setup.d.ts +0 -16
  108. package/dist/test-setup.d.ts.map +0 -1
  109. package/dist/test-setup.js +0 -40
  110. package/dist/test.d.ts +0 -2
  111. package/dist/test.d.ts.map +0 -1
  112. package/dist/test.js +0 -24
  113. /package/dist/{createState.test.d.ts → tests/createState.test.d.ts} +0 -0
  114. /package/dist/{createView.test.d.ts → tests/createView.test.d.ts} +0 -0
  115. /package/dist/{observation.test.d.ts → tests/observation.test.d.ts} +0 -0
@@ -1,2 +1,4 @@
1
- export { createVNode, createComponentVNode, createFragment, createTextVNode, normalizeProps, Component, } from "inferno";
1
+ export { createVNode, createFragment, createTextVNode, normalizeProps, Component, } from "inferno";
2
+ import { VNode } from "inferno";
3
+ export declare function createComponentVNode(_: any, component: any, props: any | undefined, key: any, ref: any): VNode;
2
4
  //# sourceMappingURL=compiler.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"compiler.d.ts","sourceRoot":"","sources":["../src/compiler.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,oBAAoB,EACpB,cAAc,EACd,eAAe,EACf,cAAc,EACd,SAAS,GACV,MAAM,SAAS,CAAC"}
1
+ {"version":3,"file":"compiler.d.ts","sourceRoot":"","sources":["../src/compiler.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,cAAc,EACd,eAAe,EACf,cAAc,EACd,SAAS,GACV,MAAM,SAAS,CAAC;AAEjB,OAAO,EAGL,KAAK,EACN,MAAM,SAAS,CAAC;AAIjB,wBAAgB,oBAAoB,CAClC,CAAC,EAAE,GAAG,EACN,SAAS,EAAE,GAAG,EACd,KAAK,EAAE,GAAG,YAAK,EACf,GAAG,EAAE,GAAG,EACR,GAAG,EAAE,GAAG,GACP,KAAK,CASP"}
package/dist/compiler.js CHANGED
@@ -1 +1,7 @@
1
- export { createVNode, createComponentVNode, createFragment, createTextVNode, normalizeProps, Component, } from "inferno";
1
+ export { createVNode, createFragment, createTextVNode, normalizeProps, Component, } from "inferno";
2
+ import { createComponentVNode as infernoCreateComponentVnode, } from "inferno";
3
+ import { RaskComponent } from "./component";
4
+ export function createComponentVNode(_, component, props = {}, key, ref) {
5
+ props.__component = component;
6
+ return infernoCreateComponentVnode(4 /* VNodeFlags.ComponentClass */, RaskComponent, props, key, ref);
7
+ }
@@ -1,25 +1,12 @@
1
1
  import { VNode, Component, Props, InfernoNode } from "inferno";
2
2
  import { Observer, Signal } from "./observation";
3
- export type RaskStatelessFunctionComponent<P extends Props<any>> = (() => VNode) | ((props: P) => VNode);
4
- export declare class RaskStatelessComponent extends Component {
5
- renderFn: RaskStatelessFunctionComponent<any>;
6
- private isNotified;
7
- private isReconciling;
8
- observer: Observer;
9
- propsSignals: Record<string, Signal>;
10
- private reactiveProps;
11
- shouldComponentUpdate(): boolean;
12
- componentWillMount(): void;
13
- componentWillReceiveProps(nextProps: any): void;
14
- render(): any;
15
- }
16
- export declare function getCurrentComponent(): RaskStatefulComponent<any> | undefined;
3
+ export declare function getCurrentComponent(): RaskComponent<any> | undefined;
17
4
  export declare function useMountEffect(cb: () => void): void;
18
5
  export declare function useCleanup(cb: () => void): void;
6
+ export type RaskStatelessFunctionComponent<P extends Props<any>> = (() => VNode) | ((props: P) => VNode);
19
7
  export type RaskStatefulFunctionComponent<P extends Props<any>> = (() => () => VNode) | ((props: P) => () => VNode);
20
- export declare class RaskStatefulComponent<P extends Props<any>> extends Component<P> {
21
- setup: RaskStatefulFunctionComponent<P>;
22
- private renderFn?;
8
+ export declare class RaskComponent<P extends Props<any>> extends Component<P> {
9
+ renderFn: RaskStatelessFunctionComponent<P>;
23
10
  propsSignals: Record<string, Signal>;
24
11
  private reactiveProps;
25
12
  private isNotified;
@@ -42,5 +29,4 @@ export declare class RaskStatefulComponent<P extends Props<any>> extends Compone
42
29
  shouldComponentUpdate(): boolean;
43
30
  render(): any;
44
31
  }
45
- export declare function createComponent(props: Props<any>, key?: string): VNode;
46
32
  //# sourceMappingURL=component.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"component.d.ts","sourceRoot":"","sources":["../src/component.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,EACL,SAAS,EACT,KAAK,EACL,WAAW,EACZ,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAsB,QAAQ,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAIrE,MAAM,MAAM,8BAA8B,CAAC,CAAC,SAAS,KAAK,CAAC,GAAG,CAAC,IAC3D,CAAC,MAAM,KAAK,CAAC,GACb,CAAC,CAAC,KAAK,EAAE,CAAC,KAAK,KAAK,CAAC,CAAC;AAE1B,qBAAa,sBAAuB,SAAQ,SAAS;IAC3C,QAAQ,EAAE,8BAA8B,CAAC,GAAG,CAAC,CAAC;IACtD,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,aAAa,CAAS;IAC9B,QAAQ,WAML;IACH,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAM;IAC1C,OAAO,CAAC,aAAa,CAAc;IAEnC,qBAAqB,IAAI,OAAO;IAMhC,kBAAkB,IAAI,IAAI;IAG1B,yBAAyB,CAAC,SAAS,EAAE,GAAG,GAAG,IAAI;IAe/C,MAAM;CAoBP;AAID,wBAAgB,mBAAmB,2CAElC;AAED,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,IAAI,QAM5C;AAED,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,IAAI,QAMxC;AAED,MAAM,MAAM,6BAA6B,CAAC,CAAC,SAAS,KAAK,CAAC,GAAG,CAAC,IAC1D,CAAC,MAAM,MAAM,KAAK,CAAC,GACnB,CAAC,CAAC,KAAK,EAAE,CAAC,KAAK,MAAM,KAAK,CAAC,CAAC;AAEhC,qBAAa,qBAAqB,CAAC,CAAC,SAAS,KAAK,CAAC,GAAG,CAAC,CAAE,SAAQ,SAAS,CAAC,CAAC,CAAC;IACnE,KAAK,EAAE,6BAA6B,CAAC,CAAC,CAAC,CAAC;IAChD,OAAO,CAAC,QAAQ,CAAC,CAAc;IAC/B,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAM;IAC1C,OAAO,CAAC,aAAa,CAAc;IAwBnC,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,aAAa,CAAS;IAE9B,QAAQ,WAOL;IAEH,WAAW,UAAS;IACpB,OAAO,EAAE,KAAK,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,GAAG,EAAE,MAAM,IAAI,CAAA;KAAE,CAAC,CAAM;IAC3D,QAAQ,gBAAa;IACrB,eAAe;IAcf,QAAQ,EAAE,KAAK,CAAC,MAAM,IAAI,CAAC,CAAM;IACjC,UAAU,EAAE,KAAK,CAAC,MAAM,IAAI,CAAC,CAAM;IAEnC,iBAAiB,IAAI,IAAI;IAGzB,oBAAoB,IAAI,IAAI;IAI5B,yBAAyB,CACvB,SAAS,EAAE,QAAQ,CAAC;QAAE,QAAQ,CAAC,EAAE,WAAW,CAAA;KAAE,GAAG,CAAC,CAAC,GAClD,IAAI;IAcP,qBAAqB,IAAI,OAAO;IAMhC,MAAM;CA2CP;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,EAAE,MAAM,SAO9D"}
1
+ {"version":3,"file":"component.d.ts","sourceRoot":"","sources":["../src/component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAC/D,OAAO,EAAsB,QAAQ,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAMrE,wBAAgB,mBAAmB,mCAElC;AAED,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,IAAI,QAM5C;AAED,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,IAAI,QAMxC;AAED,MAAM,MAAM,8BAA8B,CAAC,CAAC,SAAS,KAAK,CAAC,GAAG,CAAC,IAC3D,CAAC,MAAM,KAAK,CAAC,GACb,CAAC,CAAC,KAAK,EAAE,CAAC,KAAK,KAAK,CAAC,CAAC;AAE1B,MAAM,MAAM,6BAA6B,CAAC,CAAC,SAAS,KAAK,CAAC,GAAG,CAAC,IAC1D,CAAC,MAAM,MAAM,KAAK,CAAC,GACnB,CAAC,CAAC,KAAK,EAAE,CAAC,KAAK,MAAM,KAAK,CAAC,CAAC;AAEhC,qBAAa,aAAa,CAAC,CAAC,SAAS,KAAK,CAAC,GAAG,CAAC,CAAE,SAAQ,SAAS,CAAC,CAAC,CAAC;IAC3D,QAAQ,EAAE,8BAA8B,CAAC,CAAC,CAAC,CAAC;IACpD,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAM;IAC1C,OAAO,CAAC,aAAa,CAAc;IAwBnC,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,aAAa,CAAS;IAE9B,QAAQ,WAOL;IAEH,WAAW,UAAS;IACpB,OAAO,EAAE,KAAK,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,GAAG,EAAE,MAAM,IAAI,CAAA;KAAE,CAAC,CAAM;IAC3D,QAAQ,gBAAa;IACrB,eAAe;IAcf,QAAQ,EAAE,KAAK,CAAC,MAAM,IAAI,CAAC,CAAM;IACjC,UAAU,EAAE,KAAK,CAAC,MAAM,IAAI,CAAC,CAAM;IAEnC,iBAAiB,IAAI,IAAI;IAGzB,oBAAoB,IAAI,IAAI;IAI5B,yBAAyB,CACvB,SAAS,EAAE,QAAQ,CAAC;QAAE,QAAQ,CAAC,EAAE,WAAW,CAAA;KAAE,GAAG,CAAC,CAAC,GAClD,IAAI;IAcP,qBAAqB,IAAI,OAAO;IAMhC,MAAM;CA4CP"}
package/dist/component.js CHANGED
@@ -1,61 +1,7 @@
1
- import { createComponentVNode, Component, } from "inferno";
1
+ import { Component } from "inferno";
2
2
  import { getCurrentObserver, Observer, Signal } from "./observation";
3
3
  import { syncBatch } from "./batch";
4
4
  import { CatchErrorContext } from "./useCatchError";
5
- export class RaskStatelessComponent extends Component {
6
- isNotified = false;
7
- isReconciling = false;
8
- observer = new Observer(() => {
9
- if (this.isReconciling) {
10
- this.isNotified = true;
11
- return;
12
- }
13
- this.forceUpdate();
14
- });
15
- propsSignals = {};
16
- reactiveProps;
17
- shouldComponentUpdate() {
18
- const shouldRender = this.isNotified;
19
- this.isNotified = false;
20
- this.isReconciling = false;
21
- return shouldRender;
22
- }
23
- componentWillMount() {
24
- this.reactiveProps = createReactiveProps(this);
25
- }
26
- componentWillReceiveProps(nextProps) {
27
- this.isReconciling = true;
28
- const prevProps = this.props;
29
- this.props = nextProps;
30
- syncBatch(() => {
31
- for (const prop in this.propsSignals) {
32
- if (prevProps[prop] === nextProps[prop]) {
33
- continue;
34
- }
35
- // This just triggers the signal
36
- this.propsSignals[prop].notify();
37
- }
38
- });
39
- }
40
- render() {
41
- const stopObserving = this.observer.observe();
42
- let result = null;
43
- try {
44
- result = this.renderFn(this.reactiveProps);
45
- }
46
- catch (error) {
47
- const notifyError = CatchErrorContext.use();
48
- if (typeof notifyError !== "function") {
49
- throw error;
50
- }
51
- notifyError(error);
52
- }
53
- finally {
54
- stopObserving();
55
- }
56
- return result;
57
- }
58
- }
59
5
  let currentComponent;
60
6
  export function getCurrentComponent() {
61
7
  return currentComponent;
@@ -72,8 +18,7 @@ export function useCleanup(cb) {
72
18
  }
73
19
  currentComponent.onCleanups.push(cb);
74
20
  }
75
- export class RaskStatefulComponent extends Component {
76
- renderFn;
21
+ export class RaskComponent extends Component {
77
22
  propsSignals = {};
78
23
  reactiveProps;
79
24
  // RECONCILIATION FLAGS
@@ -152,28 +97,27 @@ export class RaskStatefulComponent extends Component {
152
97
  }
153
98
  render() {
154
99
  currentComponent = this;
155
- if (!this.renderFn) {
156
- this.reactiveProps = createReactiveProps(this);
157
- try {
158
- this.renderFn = this.setup(this.reactiveProps);
159
- if (typeof this.renderFn !== "function") {
160
- throw new Error("Component must return a render function");
100
+ const stopObserving = this.observer.observe();
101
+ try {
102
+ if (!this.renderFn) {
103
+ this.reactiveProps = createReactiveProps(this);
104
+ const component = this.props.__component;
105
+ const renderFn = component(this.reactiveProps);
106
+ if (typeof renderFn === "function") {
107
+ // Since we ran a setup function we need to clear any signals accessed
108
+ this.observer.clearSignals();
109
+ this.renderFn = renderFn;
161
110
  }
162
- }
163
- catch (error) {
164
- if (typeof this.context.notifyError !== "function") {
165
- throw error;
111
+ else {
112
+ this.renderFn = component;
113
+ return renderFn;
166
114
  }
167
- this.context.notifyError(error);
168
- return null;
169
115
  }
170
- }
171
- const stopObserving = this.observer.observe();
172
- let result = null;
173
- try {
116
+ let result = null;
174
117
  this.isRendering = true;
175
- result = this.renderFn();
118
+ result = this.renderFn(this.reactiveProps);
176
119
  this.isRendering = false;
120
+ return result;
177
121
  }
178
122
  catch (error) {
179
123
  const notifyError = CatchErrorContext.use();
@@ -181,17 +125,14 @@ export class RaskStatefulComponent extends Component {
181
125
  throw error;
182
126
  }
183
127
  notifyError(error);
128
+ return null;
184
129
  }
185
130
  finally {
186
131
  stopObserving();
187
132
  currentComponent = undefined;
188
133
  }
189
- return result;
190
134
  }
191
135
  }
192
- export function createComponent(props, key) {
193
- return createComponentVNode(4 /* VNodeFlags.ComponentClass */, RaskStatefulComponent, props, key);
194
- }
195
136
  function createReactiveProps(comp) {
196
137
  const props = new Proxy({}, {
197
138
  ownKeys() {
@@ -0,0 +1,4 @@
1
+ export declare function createComputed<T extends Record<string, () => any>>(computed: T): {
2
+ [K in keyof T]: ReturnType<T[K]>;
3
+ };
4
+ //# sourceMappingURL=createComputed.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createComputed.d.ts","sourceRoot":"","sources":["../src/createComputed.ts"],"names":[],"mappings":"AAIA,wBAAgB,cAAc,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,CAAC,EAChE,QAAQ,EAAE,CAAC,GACV;KACA,CAAC,IAAI,MAAM,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CACjC,CA0EA"}
@@ -0,0 +1,69 @@
1
+ import { getCurrentComponent, createCleanup } from "./component";
2
+ import { INSPECT_MARKER, INSPECTOR_ENABLED } from "./inspect";
3
+ import { getCurrentObserver, Observer, Signal } from "./observation";
4
+ export function createComputed(computed) {
5
+ const currentComponent = getCurrentComponent();
6
+ const proxy = {};
7
+ let notifyInspectorRef = {};
8
+ for (const prop in computed) {
9
+ let isDirty = true;
10
+ let value;
11
+ const signal = new Signal();
12
+ const computedObserver = new Observer(() => {
13
+ isDirty = true;
14
+ signal.notify();
15
+ if (INSPECTOR_ENABLED) {
16
+ notifyInspectorRef.current?.notify({
17
+ type: "computed",
18
+ path: notifyInspectorRef.current.path.concat(prop),
19
+ isDirty: true,
20
+ value,
21
+ });
22
+ }
23
+ });
24
+ createCleanup(() => computedObserver.dispose());
25
+ Object.defineProperty(proxy, prop, {
26
+ enumerable: true,
27
+ configurable: true,
28
+ get() {
29
+ const currentObserver = getCurrentObserver();
30
+ if (currentObserver) {
31
+ currentObserver.subscribeSignal(signal);
32
+ }
33
+ if (isDirty) {
34
+ const stopObserving = computedObserver.observe();
35
+ value = computed[prop]();
36
+ stopObserving();
37
+ isDirty = false;
38
+ if (INSPECTOR_ENABLED) {
39
+ notifyInspectorRef.current?.notify({
40
+ type: "computed",
41
+ path: notifyInspectorRef.current.path.concat(prop),
42
+ isDirty: false,
43
+ value,
44
+ });
45
+ }
46
+ return value;
47
+ }
48
+ return value;
49
+ },
50
+ });
51
+ }
52
+ if (INSPECTOR_ENABLED) {
53
+ Object.defineProperty(proxy, INSPECT_MARKER, {
54
+ enumerable: false,
55
+ configurable: false,
56
+ get() {
57
+ return !notifyInspectorRef.current;
58
+ },
59
+ set: (value) => {
60
+ Object.defineProperty(notifyInspectorRef, "current", {
61
+ get() {
62
+ return value.current;
63
+ },
64
+ });
65
+ },
66
+ });
67
+ }
68
+ return proxy;
69
+ }
@@ -0,0 +1,2 @@
1
+ export declare function createEffect(cb: () => void | (() => void)): void;
2
+ //# sourceMappingURL=createEffect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createEffect.d.ts","sourceRoot":"","sources":["../src/createEffect.ts"],"names":[],"mappings":"AAIA,wBAAgB,YAAY,CAAC,EAAE,EAAE,MAAM,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,QA2BzD"}
@@ -0,0 +1,29 @@
1
+ import { syncBatch } from "./batch";
2
+ import { createCleanup, getCurrentComponent } from "./component";
3
+ import { Observer } from "./observation";
4
+ export function createEffect(cb) {
5
+ const component = getCurrentComponent();
6
+ if (!component || component.isRendering) {
7
+ throw new Error("Only use createEffect in component setup");
8
+ }
9
+ let disposer;
10
+ const observer = new Observer(() => {
11
+ syncBatch(runEffect);
12
+ });
13
+ const runEffect = () => {
14
+ try {
15
+ disposer?.();
16
+ }
17
+ catch (error) {
18
+ console.error("Error in effect dispose function:", error);
19
+ }
20
+ const stopObserving = observer.observe();
21
+ disposer = cb();
22
+ stopObserving();
23
+ };
24
+ createCleanup(() => {
25
+ observer.dispose();
26
+ disposer?.();
27
+ });
28
+ runEffect();
29
+ }
@@ -0,0 +1,8 @@
1
+ import { RoutesConfig, TRouter, TRoutes } from "typed-client-router";
2
+ export type Router<T extends RoutesConfig> = Omit<TRouter<T>, "current" | "listen" | "pathname"> & {
3
+ route?: TRoutes<T>;
4
+ };
5
+ export declare function createRouter<const T extends RoutesConfig>(config: T, options?: {
6
+ base?: string;
7
+ }): Router<T>;
8
+ //# sourceMappingURL=createRouter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createRouter.d.ts","sourceRoot":"","sources":["../src/createRouter.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,YAAY,EACZ,OAAO,EACP,OAAO,EACR,MAAM,qBAAqB,CAAC;AAI7B,MAAM,MAAM,MAAM,CAAC,CAAC,SAAS,YAAY,IAAI,IAAI,CAC/C,OAAO,CAAC,CAAC,CAAC,EACV,SAAS,GAAG,QAAQ,GAAG,UAAU,CAClC,GAAG;IACF,KAAK,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;CACpB,CAAC;AAEF,wBAAgB,YAAY,CAAC,KAAK,CAAC,CAAC,SAAS,YAAY,EACvD,MAAM,EAAE,CAAC,EACT,OAAO,CAAC,EAAE;IACR,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,GACA,MAAM,CAAC,CAAC,CAAC,CA4BX"}
@@ -0,0 +1,27 @@
1
+ import { createRouter as internalCreateRouter, } from "typed-client-router";
2
+ import { getCurrentObserver, Signal } from "./observation";
3
+ import { createCleanup, getCurrentComponent } from "./component";
4
+ export function createRouter(config, options) {
5
+ if (!getCurrentComponent()) {
6
+ throw new Error("Only use createRouter in component setup");
7
+ }
8
+ const router = internalCreateRouter(config, options);
9
+ const signal = new Signal();
10
+ createCleanup(router.listen(() => signal.notify()));
11
+ return {
12
+ get route() {
13
+ const observer = getCurrentObserver();
14
+ if (observer) {
15
+ observer.subscribeSignal(signal);
16
+ }
17
+ return router.current;
18
+ },
19
+ get queries() {
20
+ return router.queries;
21
+ },
22
+ setQuery: router.setQuery,
23
+ push: router.push,
24
+ replace: router.replace,
25
+ url: router.url,
26
+ };
27
+ }
@@ -1,3 +1,4 @@
1
+ export declare function assignState<T extends object>(state: T, newState: T): T;
1
2
  /**
2
3
  * Creates a reactive state object that tracks property access and notifies observers on changes.
3
4
  *
@@ -23,4 +24,5 @@
23
24
  * @returns A reactive proxy of the state object
24
25
  */
25
26
  export declare function createState<T extends object>(state: T): T;
27
+ export declare const PROXY_MARKER: unique symbol;
26
28
  //# sourceMappingURL=createState.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"createState.d.ts","sourceRoot":"","sources":["../src/createState.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,CAEzD"}
1
+ {"version":3,"file":"createState.d.ts","sourceRoot":"","sources":["../src/createState.ts"],"names":[],"mappings":"AAIA,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,KAElE;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,CAOzD;AAGD,eAAO,MAAM,YAAY,eAAoB,CAAC"}
@@ -1,4 +1,9 @@
1
+ import { getCurrentComponent } from "./component";
2
+ import { INSPECT_MARKER, INSPECTOR_ENABLED } from "./inspect";
1
3
  import { getCurrentObserver, Signal } from "./observation";
4
+ export function assignState(state, newState) {
5
+ return Object.assign(state, newState);
6
+ }
2
7
  /**
3
8
  * Creates a reactive state object that tracks property access and notifies observers on changes.
4
9
  *
@@ -24,11 +29,14 @@ import { getCurrentObserver, Signal } from "./observation";
24
29
  * @returns A reactive proxy of the state object
25
30
  */
26
31
  export function createState(state) {
27
- return getProxy(state);
32
+ if (getCurrentComponent()?.isRendering) {
33
+ throw new Error("createState cannot be called during render. Call it in component setup or globally.");
34
+ }
35
+ return getProxy(state, {});
28
36
  }
29
37
  const proxyCache = new WeakMap();
30
- const PROXY_MARKER = Symbol("isProxy");
31
- function getProxy(value) {
38
+ export const PROXY_MARKER = Symbol("isProxy");
39
+ function getProxy(value, notifyInspectorRef) {
32
40
  // Check if already a proxy to avoid double-wrapping
33
41
  if (PROXY_MARKER in value) {
34
42
  return value;
@@ -43,6 +51,9 @@ function getProxy(value) {
43
51
  if (key === PROXY_MARKER) {
44
52
  return true;
45
53
  }
54
+ if (INSPECTOR_ENABLED && key === INSPECT_MARKER) {
55
+ return true;
56
+ }
46
57
  return Reflect.has(target, key);
47
58
  },
48
59
  get(target, key) {
@@ -50,6 +61,9 @@ function getProxy(value) {
50
61
  if (key === PROXY_MARKER) {
51
62
  return true;
52
63
  }
64
+ if (INSPECTOR_ENABLED && key === INSPECT_MARKER) {
65
+ return !notifyInspectorRef.current;
66
+ }
53
67
  const value = Reflect.get(target, key);
54
68
  if (typeof key === "symbol" || typeof value === "function") {
55
69
  return value;
@@ -61,11 +75,26 @@ function getProxy(value) {
61
75
  }
62
76
  if (Array.isArray(value) ||
63
77
  (typeof value === "object" && value !== null)) {
64
- return getProxy(value);
78
+ return getProxy(value, INSPECTOR_ENABLED && notifyInspectorRef.current
79
+ ? {
80
+ current: {
81
+ notify: notifyInspectorRef.current.notify,
82
+ path: notifyInspectorRef.current.path.concat(key),
83
+ },
84
+ }
85
+ : notifyInspectorRef);
65
86
  }
66
87
  return value;
67
88
  },
68
89
  set(target, key, newValue) {
90
+ if (INSPECTOR_ENABLED && key === INSPECT_MARKER) {
91
+ Object.defineProperty(notifyInspectorRef, "current", {
92
+ get() {
93
+ return newValue.current;
94
+ },
95
+ });
96
+ return Reflect.set(target, key, newValue);
97
+ }
69
98
  if (typeof key === "symbol") {
70
99
  return Reflect.set(target, key, newValue);
71
100
  }
@@ -73,10 +102,16 @@ function getProxy(value) {
73
102
  const setResult = Reflect.set(target, key, newValue);
74
103
  // We only notify if actual change, though array length actually updates under the hood
75
104
  if (newValue !== oldValue || (Array.isArray(value) && key === "length")) {
76
- console.log("WTF", key, newValue);
77
105
  const signal = signals[key];
78
106
  signal?.notify();
79
107
  }
108
+ if (INSPECTOR_ENABLED) {
109
+ notifyInspectorRef.current?.notify({
110
+ type: "mutation",
111
+ path: notifyInspectorRef.current.path,
112
+ value: newValue,
113
+ });
114
+ }
80
115
  return setResult;
81
116
  },
82
117
  deleteProperty(target, key) {
@@ -0,0 +1,31 @@
1
+ export type TaskState<P, T> = {
2
+ isRunning: false;
3
+ params: null;
4
+ result: null;
5
+ error: null;
6
+ } | {
7
+ isRunning: true;
8
+ result: T | null;
9
+ params: P;
10
+ error: null;
11
+ } | {
12
+ isRunning: false;
13
+ params: null;
14
+ result: T;
15
+ error: null;
16
+ } | {
17
+ isRunning: false;
18
+ params: null;
19
+ result: null;
20
+ error: string;
21
+ };
22
+ export type Task<A, B = never> = [B] extends [never] ? TaskState<null, A> & {
23
+ run(): Promise<A>;
24
+ rerun(): Promise<A>;
25
+ } : TaskState<A, B> & {
26
+ run(params: A): Promise<B>;
27
+ rerun(params: A): Promise<B>;
28
+ };
29
+ export declare function createTask<T>(task: (params: undefined, signal: AbortSignal) => Promise<T>): Task<T>;
30
+ export declare function createTask<P, T>(task: (params: P, signal: AbortSignal) => Promise<T>): Task<P, T>;
31
+ //# sourceMappingURL=createTask.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createTask.d.ts","sourceRoot":"","sources":["../src/createTask.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,SAAS,CAAC,CAAC,EAAE,CAAC,IACtB;IACE,SAAS,EAAE,KAAK,CAAC;IACjB,MAAM,EAAE,IAAI,CAAC;IACb,MAAM,EAAE,IAAI,CAAC;IACb,KAAK,EAAE,IAAI,CAAC;CACb,GACD;IACE,SAAS,EAAE,IAAI,CAAC;IAChB,MAAM,EAAE,CAAC,GAAG,IAAI,CAAC;IACjB,MAAM,EAAE,CAAC,CAAC;IACV,KAAK,EAAE,IAAI,CAAC;CACb,GACD;IACE,SAAS,EAAE,KAAK,CAAC;IACjB,MAAM,EAAE,IAAI,CAAC;IACb,MAAM,EAAE,CAAC,CAAC;IACV,KAAK,EAAE,IAAI,CAAC;CACb,GACD;IACE,SAAS,EAAE,KAAK,CAAC;IACjB,MAAM,EAAE,IAAI,CAAC;IACb,MAAM,EAAE,IAAI,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEN,MAAM,MAAM,IAAI,CAAC,CAAC,EAAE,CAAC,GAAG,KAAK,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,GAChD,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG;IACnB,GAAG,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC;IAClB,KAAK,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC;CACrB,GACD,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG;IAChB,GAAG,CAAC,MAAM,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAC3B,KAAK,CAAC,MAAM,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;CAC9B,CAAC;AAEN,wBAAgB,UAAU,CAAC,CAAC,EAC1B,IAAI,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC,CAAC,CAAC,GAC3D,IAAI,CAAC,CAAC,CAAC,CAAC;AACX,wBAAgB,UAAU,CAAC,CAAC,EAAE,CAAC,EAC7B,IAAI,EAAE,CAAC,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC,CAAC,CAAC,GACnD,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC"}
@@ -0,0 +1,79 @@
1
+ import { createCleanup, getCurrentComponent } from "./component";
2
+ import { assignState, createState } from "./createState";
3
+ export function createTask(task) {
4
+ const currentComponent = getCurrentComponent();
5
+ if (!currentComponent || currentComponent.isRendering) {
6
+ throw new Error("Only use createTask in component setup");
7
+ }
8
+ const state = createState({
9
+ isRunning: false,
10
+ result: null,
11
+ error: null,
12
+ params: null,
13
+ });
14
+ let currentAbortController;
15
+ const fetch = (params) => {
16
+ currentAbortController?.abort();
17
+ const abortController = (currentAbortController = new AbortController());
18
+ const promise = task(params, abortController.signal);
19
+ promise
20
+ .then((result) => {
21
+ if (abortController.signal.aborted) {
22
+ return;
23
+ }
24
+ assignState(state, {
25
+ isRunning: false,
26
+ result,
27
+ error: null,
28
+ params: null,
29
+ });
30
+ })
31
+ .catch((error) => {
32
+ if (abortController.signal.aborted) {
33
+ return;
34
+ }
35
+ assignState(state, {
36
+ isRunning: false,
37
+ result: null,
38
+ error: String(error),
39
+ params: null,
40
+ });
41
+ });
42
+ return promise;
43
+ };
44
+ createCleanup(() => currentAbortController?.abort());
45
+ return {
46
+ get isRunning() {
47
+ return state.isRunning;
48
+ },
49
+ get result() {
50
+ return state.result;
51
+ },
52
+ get error() {
53
+ return state.error;
54
+ },
55
+ get params() {
56
+ return state.params;
57
+ },
58
+ run(params) {
59
+ const promise = fetch(params);
60
+ assignState(state, {
61
+ isRunning: true,
62
+ result: null,
63
+ error: null,
64
+ params: (params || null),
65
+ });
66
+ return promise;
67
+ },
68
+ rerun(params) {
69
+ const promise = fetch(params);
70
+ assignState(state, {
71
+ isRunning: true,
72
+ result: state.result,
73
+ error: null,
74
+ params: (params || null),
75
+ });
76
+ return promise;
77
+ },
78
+ };
79
+ }
@@ -1,54 +1,28 @@
1
- type Simplify<T> = {
1
+ type Simplify<T> = T extends any ? {
2
2
  [K in keyof T]: T[K];
3
- } & {};
4
- type MergeTwo<A extends object, B extends object> = Simplify<Omit<A, keyof B> & B>;
3
+ } : never;
4
+ type UndefinedKeys<T> = {
5
+ [K in keyof T]-?: [T[K]] extends [undefined] ? K : never;
6
+ }[keyof T];
7
+ type MergeTwo<A extends object, B extends object> = A extends any ? Simplify<Omit<A, keyof B> & Omit<B, UndefinedKeys<B>>> : never;
5
8
  type MergeMany<T extends readonly object[]> = T extends [
6
9
  infer H extends object,
7
10
  ...infer R extends object[]
8
- ] ? MergeTwo<H, MergeMany<R>> : {};
11
+ ] ? MergeManyAcc<H, R> : {};
12
+ type MergeManyAcc<Acc extends object, Rest extends object[]> = Rest extends [
13
+ infer H extends object,
14
+ ...infer R extends object[]
15
+ ] ? MergeManyAcc<MergeTwo<Acc, H>, R> : Acc;
9
16
  /**
10
- * Creates a view that merges multiple objects (reactive or not) into a single object while
11
- * maintaining reactivity through getters. Properties from later arguments override earlier ones.
12
- *
13
- * @warning **Do not destructure the returned view object!** Destructuring breaks reactivity
14
- * because it extracts plain values instead of maintaining getter access. This is the same rule
15
- * as other reactive primitives.
16
- *
17
- * @example
18
- * // ❌ Bad - destructuring loses reactivity
19
- * function Component() {
20
- * const state = createState({ count: 0 });
21
- * const helpers = { increment: () => state.count++ };
22
- * const view = createView(state, helpers);
23
- * const { count, increment } = view; // Don't do this!
24
- * return () => <button onClick={increment}>{count}</button>; // Won't update!
25
- * }
26
- *
27
- * // ✅ Good - access properties directly in render
28
- * function Component() {
29
- * const state = createState({ count: 0 });
30
- * const helpers = { increment: () => state.count++ };
31
- * const view = createView(state, helpers);
32
- * return () => <button onClick={view.increment}>{view.count}</button>; // Reactive!
33
- * }
34
- *
35
- * @example
36
- * // Merge multiple reactive objects
37
- * const state = createState({ count: 0 });
38
- * const user = createState({ name: "Alice" });
39
- * const view = createView(state, user);
40
- * // view has both count and name properties, maintaining reactivity
41
- *
42
- * @example
43
- * // Later arguments override earlier ones
44
- * const a = { x: 1, y: 2 };
45
- * const b = { y: 3, z: 4 };
46
- * const view = createView(a, b);
47
- * // view.x === 1, view.y === 3, view.z === 4
17
+ * Creates a view that merges multiple objects (reactive or not) into a single
18
+ * object while maintaining reactivity through getters. Properties from later
19
+ * arguments override earlier ones.
48
20
  *
49
- * @param args - Objects to merge (reactive or plain objects)
50
- * @returns A view object with getters for all properties, maintaining reactivity
21
+ * ⚠️ Do not destructure the returned view object; always read properties
22
+ * directly from the view to preserve reactivity.
51
23
  */
24
+ export declare function createView<A extends object>(a: A): A;
25
+ export declare function createView<A extends object, B extends object>(a: A, b: B): MergeTwo<A, B>;
52
26
  export declare function createView<T extends readonly object[]>(...args: T): MergeMany<T>;
53
27
  export {};
54
28
  //# sourceMappingURL=createView.d.ts.map