@virentia/react 0.2.2 → 0.2.3

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 CHANGED
@@ -200,6 +200,9 @@ function useModelInstance(factory, props, scope, options) {
200
200
  }
201
201
  function useModelInstanceLifecycle(instance, props, options) {
202
202
  const scope = instance.scope;
203
+ const mountCountsRef = (0, react.useRef)(null);
204
+ if (mountCountsRef.current === null) mountCountsRef.current = /* @__PURE__ */ new WeakMap();
205
+ const mountCounts = mountCountsRef.current;
203
206
  useIsomorphicLayoutEffect(() => {
204
207
  writeStore(instance.props, props, scope);
205
208
  }, [
@@ -208,21 +211,26 @@ function useModelInstanceLifecycle(instance, props, options) {
208
211
  scope
209
212
  ]);
210
213
  (0, react.useEffect)(() => {
214
+ mountCounts.set(instance, (mountCounts.get(instance) ?? 0) + 1);
211
215
  (0, _virentia_core.scoped)(scope, () => {
212
216
  instance.mounts.value += 1;
213
217
  instance.mounted();
214
218
  });
215
219
  return () => {
220
+ mountCounts.set(instance, Math.max(0, (mountCounts.get(instance) ?? 1) - 1));
216
221
  (0, _virentia_core.scoped)(scope, () => {
217
222
  instance.mounts.value = Math.max(0, instance.mounts.value - 1);
218
223
  instance.unmounted();
219
224
  });
220
- if (options.disposeOnUnmount) instance.dispose();
225
+ if (options.disposeOnUnmount) queueMicrotask(() => {
226
+ if ((mountCounts.get(instance) ?? 0) === 0) instance.dispose();
227
+ });
221
228
  };
222
229
  }, [
223
230
  instance,
224
231
  options.disposeOnUnmount,
225
- scope
232
+ scope,
233
+ mountCounts
226
234
  ]);
227
235
  }
228
236
  function createModelInstance(factory, props, scope, key) {
@@ -230,7 +238,7 @@ function createModelInstance(factory, props, scope, key) {
230
238
  const context = {
231
239
  scope,
232
240
  owner: modelOwner,
233
- props: (0, _virentia_core.store)(props),
241
+ props: (0, _virentia_core.reactive)(props),
234
242
  mounted: (0, _virentia_core.event)(),
235
243
  unmounted: (0, _virentia_core.event)(),
236
244
  mounts: (0, _virentia_core.store)(0),
package/dist/index.d.cts CHANGED
@@ -1,15 +1,16 @@
1
- import { DisposableOwner, Effect, EffectCallArgs, EventCallable, EventPayload, Owner, Scope, Store, StoreWritable } from "@virentia/core";
1
+ import { DisposableOwner, Effect, EffectCallArgs, EventCallable, EventPayload, Owner, Reactive, ReactiveWritable, Scope, Store, StoreWritable } from "@virentia/core";
2
2
  import { ComponentType, FC, ReactNode } from "react";
3
3
 
4
4
  //#region lib/types.d.ts
5
- type UnitLike = Store<any> | StoreWritable<any> | EventCallable<any> | Effect<any, any, any>;
5
+ type AnyStore<State = any> = Store<State> | StoreWritable<State> | Reactive<State> | ReactiveWritable<State>;
6
+ type UnitLike = AnyStore | EventCallable<any> | Effect<any, any, any>;
6
7
  declare const componentModelBrand: unique symbol;
7
- type UnitValue<Unit> = Unit extends Store<infer State> | StoreWritable<infer State> ? State : Unit extends EventCallable<infer Payload> ? (...payload: EventPayload<Payload>) => Promise<void> : Unit extends Effect<infer Params, infer Done, any> ? (...args: EffectCallArgs<Params>) => Promise<Done> : never;
8
+ type UnitValue<Unit> = Unit extends AnyStore<infer State> ? State : Unit extends EventCallable<infer Payload> ? (...payload: EventPayload<Payload>) => Promise<void> : Unit extends Effect<infer Params, infer Done, any> ? (...args: EffectCallArgs<Params>) => Promise<Done> : never;
8
9
  type ReactiveModel<Model> = { readonly [Key in keyof Model as Key extends "dispose" ? never : Key]: Model[Key] extends ComponentModel<infer ChildModel> ? ComponentModel<ChildModel> : Model[Key] extends UnitLike ? UnitValue<Model[Key]> : Model[Key] extends ((...args: any[]) => any) ? Model[Key] : Model[Key] extends object ? ReactiveModel<Model[Key]> : Model[Key] };
9
10
  interface ModelContext<Props, Key = undefined> {
10
11
  readonly scope: Scope;
11
12
  readonly owner: Owner;
12
- readonly props: StoreWritable<Props>;
13
+ readonly props: ReactiveWritable<Props>;
13
14
  readonly mounted: EventCallable<void>;
14
15
  readonly unmounted: EventCallable<void>;
15
16
  readonly mounts: StoreWritable<number>;
@@ -81,6 +82,8 @@ declare function useModel<Props, Key, Model extends object>(factory: ModelFactor
81
82
  //#region lib/use-unit.d.ts
82
83
  declare function useUnit<State>(unit: StoreWritable<State>): State;
83
84
  declare function useUnit<State>(unit: Store<State>): State;
85
+ declare function useUnit<State>(unit: ReactiveWritable<State>): State;
86
+ declare function useUnit<State>(unit: Reactive<State>): State;
84
87
  declare function useUnit<Payload>(unit: EventCallable<Payload>): UnitValue<EventCallable<Payload>>;
85
88
  declare function useUnit<Params, Done, Fail>(unit: Effect<Params, Done, Fail>): UnitValue<Effect<Params, Done, Fail>>;
86
89
  declare function useUnit<const Shape extends readonly UnitLike[]>(shape: Shape): UnitShape<Shape>;
package/dist/index.d.mts CHANGED
@@ -1,15 +1,16 @@
1
- import { DisposableOwner, Effect, EffectCallArgs, EventCallable, EventPayload, Owner, Scope, Store, StoreWritable } from "@virentia/core";
1
+ import { DisposableOwner, Effect, EffectCallArgs, EventCallable, EventPayload, Owner, Reactive, ReactiveWritable, Scope, Store, StoreWritable } from "@virentia/core";
2
2
  import { ComponentType, FC, ReactNode } from "react";
3
3
 
4
4
  //#region lib/types.d.ts
5
- type UnitLike = Store<any> | StoreWritable<any> | EventCallable<any> | Effect<any, any, any>;
5
+ type AnyStore<State = any> = Store<State> | StoreWritable<State> | Reactive<State> | ReactiveWritable<State>;
6
+ type UnitLike = AnyStore | EventCallable<any> | Effect<any, any, any>;
6
7
  declare const componentModelBrand: unique symbol;
7
- type UnitValue<Unit> = Unit extends Store<infer State> | StoreWritable<infer State> ? State : Unit extends EventCallable<infer Payload> ? (...payload: EventPayload<Payload>) => Promise<void> : Unit extends Effect<infer Params, infer Done, any> ? (...args: EffectCallArgs<Params>) => Promise<Done> : never;
8
+ type UnitValue<Unit> = Unit extends AnyStore<infer State> ? State : Unit extends EventCallable<infer Payload> ? (...payload: EventPayload<Payload>) => Promise<void> : Unit extends Effect<infer Params, infer Done, any> ? (...args: EffectCallArgs<Params>) => Promise<Done> : never;
8
9
  type ReactiveModel<Model> = { readonly [Key in keyof Model as Key extends "dispose" ? never : Key]: Model[Key] extends ComponentModel<infer ChildModel> ? ComponentModel<ChildModel> : Model[Key] extends UnitLike ? UnitValue<Model[Key]> : Model[Key] extends ((...args: any[]) => any) ? Model[Key] : Model[Key] extends object ? ReactiveModel<Model[Key]> : Model[Key] };
9
10
  interface ModelContext<Props, Key = undefined> {
10
11
  readonly scope: Scope;
11
12
  readonly owner: Owner;
12
- readonly props: StoreWritable<Props>;
13
+ readonly props: ReactiveWritable<Props>;
13
14
  readonly mounted: EventCallable<void>;
14
15
  readonly unmounted: EventCallable<void>;
15
16
  readonly mounts: StoreWritable<number>;
@@ -81,6 +82,8 @@ declare function useModel<Props, Key, Model extends object>(factory: ModelFactor
81
82
  //#region lib/use-unit.d.ts
82
83
  declare function useUnit<State>(unit: StoreWritable<State>): State;
83
84
  declare function useUnit<State>(unit: Store<State>): State;
85
+ declare function useUnit<State>(unit: ReactiveWritable<State>): State;
86
+ declare function useUnit<State>(unit: Reactive<State>): State;
84
87
  declare function useUnit<Payload>(unit: EventCallable<Payload>): UnitValue<EventCallable<Payload>>;
85
88
  declare function useUnit<Params, Done, Fail>(unit: Effect<Params, Done, Fail>): UnitValue<Effect<Params, Done, Fail>>;
86
89
  declare function useUnit<const Shape extends readonly UnitLike[]>(shape: Shape): UnitShape<Shape>;
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { event, getCurrentScope, owner, run, scoped, store } from "@virentia/core";
1
+ import { event, getCurrentScope, owner, reactive, run, scoped, store } from "@virentia/core";
2
2
  import { createContext, createElement, useCallback, useContext, useEffect, useLayoutEffect, useMemo, useRef, useSyncExternalStore } from "react";
3
3
  //#region lib/model-cache.ts
4
4
  function createModelCache() {
@@ -199,6 +199,9 @@ function useModelInstance(factory, props, scope, options) {
199
199
  }
200
200
  function useModelInstanceLifecycle(instance, props, options) {
201
201
  const scope = instance.scope;
202
+ const mountCountsRef = useRef(null);
203
+ if (mountCountsRef.current === null) mountCountsRef.current = /* @__PURE__ */ new WeakMap();
204
+ const mountCounts = mountCountsRef.current;
202
205
  useIsomorphicLayoutEffect(() => {
203
206
  writeStore(instance.props, props, scope);
204
207
  }, [
@@ -207,21 +210,26 @@ function useModelInstanceLifecycle(instance, props, options) {
207
210
  scope
208
211
  ]);
209
212
  useEffect(() => {
213
+ mountCounts.set(instance, (mountCounts.get(instance) ?? 0) + 1);
210
214
  scoped(scope, () => {
211
215
  instance.mounts.value += 1;
212
216
  instance.mounted();
213
217
  });
214
218
  return () => {
219
+ mountCounts.set(instance, Math.max(0, (mountCounts.get(instance) ?? 1) - 1));
215
220
  scoped(scope, () => {
216
221
  instance.mounts.value = Math.max(0, instance.mounts.value - 1);
217
222
  instance.unmounted();
218
223
  });
219
- if (options.disposeOnUnmount) instance.dispose();
224
+ if (options.disposeOnUnmount) queueMicrotask(() => {
225
+ if ((mountCounts.get(instance) ?? 0) === 0) instance.dispose();
226
+ });
220
227
  };
221
228
  }, [
222
229
  instance,
223
230
  options.disposeOnUnmount,
224
- scope
231
+ scope,
232
+ mountCounts
225
233
  ]);
226
234
  }
227
235
  function createModelInstance(factory, props, scope, key) {
@@ -229,7 +237,7 @@ function createModelInstance(factory, props, scope, key) {
229
237
  const context = {
230
238
  scope,
231
239
  owner: modelOwner,
232
- props: store(props),
240
+ props: reactive(props),
233
241
  mounted: event(),
234
242
  unmounted: event(),
235
243
  mounts: store(0),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@virentia/react",
3
- "version": "0.2.2",
3
+ "version": "0.2.3",
4
4
  "description": "",
5
5
  "keywords": [],
6
6
  "homepage": "https://movpushmov.dev/virentia/react/",
@@ -32,7 +32,7 @@
32
32
  "access": "public"
33
33
  },
34
34
  "dependencies": {
35
- "@virentia/core": "0.3.0"
35
+ "@virentia/core": "0.3.1"
36
36
  },
37
37
  "devDependencies": {
38
38
  "@testing-library/react": "^16.3.0",