floppy-disk 3.0.0-alpha.1 → 3.0.0-alpha.2

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,4 +1,4 @@
1
- import { type InitStoreOptions, type SetState } from 'floppy-disk';
1
+ import { type InitStoreOptions, type SetState } from 'floppy-disk/vanilla';
2
2
  /**
3
3
  * Represents the state of a mutation.
4
4
  *
@@ -90,8 +90,8 @@ export type MutationOptions<TData, TVariable> = InitStoreOptions<MutationState<T
90
90
  * const result = await useCreateUser.execute({ name: 'John' });
91
91
  */
92
92
  export declare const createMutation: <TData, TVariable = undefined>(mutationFn: (variable: TVariable, stateBeforeExecute: MutationState<TData, TVariable>) => Promise<TData>, options?: MutationOptions<TData, TVariable>) => (<TStateSlice = MutationState<TData, TVariable>>(selector?: (state: MutationState<TData, TVariable>) => TStateSlice) => TStateSlice) & {
93
- subscribe: (subscriber: import("floppy-disk").Subscriber<MutationState<TData, TVariable>>) => () => void;
94
- getSubscribers: () => Set<import("floppy-disk").Subscriber<MutationState<TData, TVariable>>>;
93
+ subscribe: (subscriber: import("../vanilla.d.mts").Subscriber<MutationState<TData, TVariable>>) => () => void;
94
+ getSubscribers: () => Set<import("../vanilla.d.mts").Subscriber<MutationState<TData, TVariable>>>;
95
95
  getState: () => MutationState<TData, TVariable>;
96
96
  /**
97
97
  * Manually updates the mutation state.
@@ -1,4 +1,4 @@
1
- import { type InitStoreOptions, type SetState } from 'floppy-disk';
1
+ import { type InitStoreOptions, type SetState } from 'floppy-disk/vanilla';
2
2
  /**
3
3
  * Represents the state of a query.
4
4
  *
@@ -285,8 +285,8 @@ export declare const createQuery: <TData, TVariable extends Record<string, any>
285
285
  * - Should be used if an optimistic update fails.
286
286
  */
287
287
  rollbackOptimisticUpdate: () => TData;
288
- subscribe: (subscriber: import("floppy-disk").Subscriber<QueryState<TData>>) => () => void;
289
- getSubscribers: () => Set<import("floppy-disk").Subscriber<QueryState<TData>>>;
288
+ subscribe: (subscriber: import("../vanilla.d.mts").Subscriber<QueryState<TData>>) => () => void;
289
+ getSubscribers: () => Set<import("../vanilla.d.mts").Subscriber<QueryState<TData>>>;
290
290
  getState: () => QueryState<TData>;
291
291
  setState: (value: SetState<QueryState<TData>>) => void;
292
292
  }) & {
@@ -1,4 +1,4 @@
1
- import { type InitStoreOptions } from 'floppy-disk';
1
+ import { type InitStoreOptions } from 'floppy-disk/vanilla';
2
2
  /**
3
3
  * Creates a single store with a bound React hook.
4
4
  *
@@ -22,4 +22,4 @@ import { type InitStoreOptions } from 'floppy-disk';
22
22
  *
23
23
  * useCounter.setState({ count: 1 });
24
24
  */
25
- export declare const createStore: <TState extends Record<string, any>>(initialState: TState, options?: InitStoreOptions<TState>) => (<TStateSlice = TState>(selector?: (state: TState) => TStateSlice) => TStateSlice) & import("floppy-disk").StoreApi<TState>;
25
+ export declare const createStore: <TState extends Record<string, any>>(initialState: TState, options?: InitStoreOptions<TState>) => (<TStateSlice = TState>(selector?: (state: TState) => TStateSlice) => TStateSlice) & import("../vanilla.d.mts").StoreApi<TState>;
@@ -1,4 +1,4 @@
1
- import { type InitStoreOptions } from 'floppy-disk';
1
+ import { type InitStoreOptions } from 'floppy-disk/vanilla';
2
2
  /**
3
3
  * Creates a factory for multiple stores identified by a key.
4
4
  *
@@ -25,8 +25,8 @@ import { type InitStoreOptions } from 'floppy-disk';
25
25
  */
26
26
  export declare const createStores: <TState extends Record<string, any>, TKey extends Record<string, any>>(initialState: TState, options?: InitStoreOptions<TState>) => (key?: TKey) => (<TStateSlice = TState>(selector?: (state: TState) => TStateSlice) => TStateSlice) & {
27
27
  delete: () => boolean;
28
- setState: (value: import("floppy-disk").SetState<TState>) => void;
28
+ setState: (value: import("../vanilla.d.mts").SetState<TState>) => void;
29
29
  getState: () => TState;
30
- subscribe: (subscriber: import("floppy-disk").Subscriber<TState>) => () => void;
31
- getSubscribers: () => Set<import("floppy-disk").Subscriber<TState>>;
30
+ subscribe: (subscriber: import("../vanilla.d.mts").Subscriber<TState>) => () => void;
31
+ getSubscribers: () => Set<import("../vanilla.d.mts").Subscriber<TState>>;
32
32
  };
@@ -1,4 +1,4 @@
1
- import { type StoreApi } from 'floppy-disk';
1
+ import { type StoreApi } from 'floppy-disk/vanilla';
2
2
  export declare const useStoreUpdateNotifier: <TState extends Record<string, any>, TStateSlice = TState>(store: StoreApi<TState>, selector: (state: TState) => TStateSlice) => void;
3
3
  /**
4
4
  * React hook for subscribing to a store with optional state selection.
package/esm/react.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import { useLayoutEffect, useEffect, useState, useRef } from 'react';
2
- import { isClient, identity, shallow, initStore, getHash, noop } from 'floppy-disk';
2
+ import { isClient, identity, shallow, initStore, getHash, noop } from 'floppy-disk/vanilla';
3
3
 
4
4
  const useIsomorphicLayoutEffect = isClient ? useLayoutEffect : useEffect;
5
5
 
@@ -13,16 +13,16 @@ export type SetState<TState> = Partial<TState> | ((state: TState) => Partial<TSt
13
13
  * @param prevState - The previous state before the update
14
14
  *
15
15
  * @remarks
16
- * - Subscribers are always called on every `setState`, regardless of equality.
17
- * - It is the subscriber's responsibility to perform comparisons if needed.
16
+ * - Subscribers are only called when the state actually changes.
17
+ * - Change detection is performed per key using `Object.is`.
18
18
  */
19
19
  export type Subscriber<TState> = (state: TState, prevState: TState) => void;
20
20
  /**
21
21
  * Core store API for managing state.
22
22
  *
23
23
  * @remarks
24
- * - The store is intentionally simple and always notifies subscribers on updates.
25
- * - No internal equality checks are performed.
24
+ * - The store performs **shallow change detection per key** before notifying subscribers.
25
+ * - Subscribers are only notified when at least one field changes.
26
26
  * - Designed to be framework-agnostic (React bindings are built separately).
27
27
  */
28
28
  export type StoreApi<TState extends Record<string, any>> = {
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "floppy-disk",
3
3
  "description": "Lightweight, simple, and powerful state management library",
4
4
  "private": false,
5
- "version": "3.0.0-alpha.1",
5
+ "version": "3.0.0-alpha.2",
6
6
  "publishConfig": {
7
7
  "tag": "alpha"
8
8
  },
@@ -1,4 +1,4 @@
1
- import { type InitStoreOptions, type SetState } from 'floppy-disk';
1
+ import { type InitStoreOptions, type SetState } from 'floppy-disk/vanilla';
2
2
  /**
3
3
  * Represents the state of a mutation.
4
4
  *
@@ -90,8 +90,8 @@ export type MutationOptions<TData, TVariable> = InitStoreOptions<MutationState<T
90
90
  * const result = await useCreateUser.execute({ name: 'John' });
91
91
  */
92
92
  export declare const createMutation: <TData, TVariable = undefined>(mutationFn: (variable: TVariable, stateBeforeExecute: MutationState<TData, TVariable>) => Promise<TData>, options?: MutationOptions<TData, TVariable>) => (<TStateSlice = MutationState<TData, TVariable>>(selector?: (state: MutationState<TData, TVariable>) => TStateSlice) => TStateSlice) & {
93
- subscribe: (subscriber: import("floppy-disk").Subscriber<MutationState<TData, TVariable>>) => () => void;
94
- getSubscribers: () => Set<import("floppy-disk").Subscriber<MutationState<TData, TVariable>>>;
93
+ subscribe: (subscriber: import("../vanilla.ts").Subscriber<MutationState<TData, TVariable>>) => () => void;
94
+ getSubscribers: () => Set<import("../vanilla.ts").Subscriber<MutationState<TData, TVariable>>>;
95
95
  getState: () => MutationState<TData, TVariable>;
96
96
  /**
97
97
  * Manually updates the mutation state.
@@ -1,4 +1,4 @@
1
- import { type InitStoreOptions, type SetState } from 'floppy-disk';
1
+ import { type InitStoreOptions, type SetState } from 'floppy-disk/vanilla';
2
2
  /**
3
3
  * Represents the state of a query.
4
4
  *
@@ -285,8 +285,8 @@ export declare const createQuery: <TData, TVariable extends Record<string, any>
285
285
  * - Should be used if an optimistic update fails.
286
286
  */
287
287
  rollbackOptimisticUpdate: () => TData;
288
- subscribe: (subscriber: import("floppy-disk").Subscriber<QueryState<TData>>) => () => void;
289
- getSubscribers: () => Set<import("floppy-disk").Subscriber<QueryState<TData>>>;
288
+ subscribe: (subscriber: import("../vanilla.ts").Subscriber<QueryState<TData>>) => () => void;
289
+ getSubscribers: () => Set<import("../vanilla.ts").Subscriber<QueryState<TData>>>;
290
290
  getState: () => QueryState<TData>;
291
291
  setState: (value: SetState<QueryState<TData>>) => void;
292
292
  }) & {
@@ -1,4 +1,4 @@
1
- import { type InitStoreOptions } from 'floppy-disk';
1
+ import { type InitStoreOptions } from 'floppy-disk/vanilla';
2
2
  /**
3
3
  * Creates a single store with a bound React hook.
4
4
  *
@@ -22,4 +22,4 @@ import { type InitStoreOptions } from 'floppy-disk';
22
22
  *
23
23
  * useCounter.setState({ count: 1 });
24
24
  */
25
- export declare const createStore: <TState extends Record<string, any>>(initialState: TState, options?: InitStoreOptions<TState>) => (<TStateSlice = TState>(selector?: (state: TState) => TStateSlice) => TStateSlice) & import("floppy-disk").StoreApi<TState>;
25
+ export declare const createStore: <TState extends Record<string, any>>(initialState: TState, options?: InitStoreOptions<TState>) => (<TStateSlice = TState>(selector?: (state: TState) => TStateSlice) => TStateSlice) & import("../vanilla.ts").StoreApi<TState>;
@@ -1,4 +1,4 @@
1
- import { type InitStoreOptions } from 'floppy-disk';
1
+ import { type InitStoreOptions } from 'floppy-disk/vanilla';
2
2
  /**
3
3
  * Creates a factory for multiple stores identified by a key.
4
4
  *
@@ -25,8 +25,8 @@ import { type InitStoreOptions } from 'floppy-disk';
25
25
  */
26
26
  export declare const createStores: <TState extends Record<string, any>, TKey extends Record<string, any>>(initialState: TState, options?: InitStoreOptions<TState>) => (key?: TKey) => (<TStateSlice = TState>(selector?: (state: TState) => TStateSlice) => TStateSlice) & {
27
27
  delete: () => boolean;
28
- setState: (value: import("floppy-disk").SetState<TState>) => void;
28
+ setState: (value: import("../vanilla.ts").SetState<TState>) => void;
29
29
  getState: () => TState;
30
- subscribe: (subscriber: import("floppy-disk").Subscriber<TState>) => () => void;
31
- getSubscribers: () => Set<import("floppy-disk").Subscriber<TState>>;
30
+ subscribe: (subscriber: import("../vanilla.ts").Subscriber<TState>) => () => void;
31
+ getSubscribers: () => Set<import("../vanilla.ts").Subscriber<TState>>;
32
32
  };
@@ -1,4 +1,4 @@
1
- import { type StoreApi } from 'floppy-disk';
1
+ import { type StoreApi } from 'floppy-disk/vanilla';
2
2
  export declare const useStoreUpdateNotifier: <TState extends Record<string, any>, TStateSlice = TState>(store: StoreApi<TState>, selector: (state: TState) => TStateSlice) => void;
3
3
  /**
4
4
  * React hook for subscribing to a store with optional state selection.
package/react.js CHANGED
@@ -1,9 +1,9 @@
1
1
  'use strict';
2
2
 
3
3
  var react = require('react');
4
- var floppyDisk = require('floppy-disk');
4
+ var vanilla = require('floppy-disk/vanilla');
5
5
 
6
- const useIsomorphicLayoutEffect = floppyDisk.isClient ? react.useLayoutEffect : react.useEffect;
6
+ const useIsomorphicLayoutEffect = vanilla.isClient ? react.useLayoutEffect : react.useEffect;
7
7
 
8
8
  const useStoreUpdateNotifier = (store, selector) => {
9
9
  const [, reRender] = react.useState({});
@@ -11,21 +11,21 @@ const useStoreUpdateNotifier = (store, selector) => {
11
11
  selectorRef.current = selector;
12
12
  useIsomorphicLayoutEffect(
13
13
  () => store.subscribe((state, prevState) => {
14
- if (selectorRef.current === floppyDisk.identity) return reRender({});
14
+ if (selectorRef.current === vanilla.identity) return reRender({});
15
15
  const prevSlice = selectorRef.current(prevState);
16
16
  const nextSlice = selectorRef.current(state);
17
- if (!floppyDisk.shallow(prevSlice, nextSlice)) reRender({});
17
+ if (!vanilla.shallow(prevSlice, nextSlice)) reRender({});
18
18
  }),
19
19
  [store]
20
20
  );
21
21
  };
22
- const useStoreState = (store, selector = floppyDisk.identity) => {
22
+ const useStoreState = (store, selector = vanilla.identity) => {
23
23
  useStoreUpdateNotifier(store, selector);
24
24
  return selector(store.getState());
25
25
  };
26
26
 
27
27
  const createStore = (initialState, options) => {
28
- const store = floppyDisk.initStore(initialState, options);
28
+ const store = vanilla.initStore(initialState, options);
29
29
  const useStore = (selector) => useStoreState(store, selector);
30
30
  return Object.assign(useStore, store);
31
31
  };
@@ -33,12 +33,12 @@ const createStore = (initialState, options) => {
33
33
  const createStores = (initialState, options) => {
34
34
  const stores = /* @__PURE__ */ new Map();
35
35
  const getStore = (key = {}) => {
36
- const keyHash = floppyDisk.getHash(key);
36
+ const keyHash = vanilla.getHash(key);
37
37
  let store;
38
38
  if (stores.has(keyHash)) {
39
39
  store = stores.get(keyHash);
40
40
  } else {
41
- store = floppyDisk.initStore(initialState, options);
41
+ store = vanilla.initStore(initialState, options);
42
42
  stores.set(keyHash, store);
43
43
  }
44
44
  const useStore = (selector) => {
@@ -82,9 +82,9 @@ const createQuery = (queryFn, options = {}) => {
82
82
  // 5 minutes
83
83
  revalidateOnFocus = true,
84
84
  revalidateOnReconnect = true,
85
- onSuccess = floppyDisk.noop,
85
+ onSuccess = vanilla.noop,
86
86
  onError,
87
- onSettled = floppyDisk.noop,
87
+ onSettled = vanilla.noop,
88
88
  shouldRetry: shouldRetryFn = (_, s) => s.retryCount === 0 ? [true, 1500] : [false]
89
89
  } = options;
90
90
  const initialState = INITIAL_STATE$1;
@@ -96,7 +96,7 @@ const createQuery = (queryFn, options = {}) => {
96
96
  (_a = options.onFirstSubscribe) == null ? void 0 : _a.call(options, state, store);
97
97
  const { metadata, revalidate: revalidate2 } = internals.get(store);
98
98
  clearTimeout(metadata.garbageCollectionTimeoutId);
99
- if (floppyDisk.isClient) {
99
+ if (vanilla.isClient) {
100
100
  if (revalidateOnFocus) {
101
101
  focusListeners.add(revalidate2);
102
102
  if (!focusListenersAdded) {
@@ -123,7 +123,7 @@ const createQuery = (queryFn, options = {}) => {
123
123
  metadata.garbageCollectionTimeoutId = setTimeout(() => {
124
124
  store.setState(initialState);
125
125
  }, gcTime);
126
- if (floppyDisk.isClient) {
126
+ if (vanilla.isClient) {
127
127
  if (revalidateOnFocus) {
128
128
  focusListeners.delete(revalidate2);
129
129
  if (focusListeners.size === 0) {
@@ -316,16 +316,16 @@ const createQuery = (queryFn, options = {}) => {
316
316
  return execute(store, variable, overwriteOngoingExecution);
317
317
  };
318
318
  const getStore = (variable = {}) => {
319
- const variableHash = floppyDisk.getHash(variable);
319
+ const variableHash = vanilla.getHash(variable);
320
320
  let store;
321
321
  if (stores.has(variableHash)) {
322
322
  store = stores.get(variableHash);
323
323
  } else {
324
- store = floppyDisk.initStore(initialState, configureStoreEvents());
324
+ store = vanilla.initStore(initialState, configureStoreEvents());
325
325
  stores.set(variableHash, store);
326
326
  internals.set(store, configureInternals(store, variable, variableHash));
327
327
  }
328
- const useStore = (options2 = {}, selector = floppyDisk.identity) => {
328
+ const useStore = (options2 = {}, selector = vanilla.identity) => {
329
329
  useStoreUpdateNotifier(store, selector);
330
330
  useIsomorphicLayoutEffect(() => {
331
331
  if (options2.enabled !== false) revalidate(store, variable);
@@ -407,9 +407,9 @@ const INITIAL_STATE = {
407
407
  errorUpdatedAt: void 0
408
408
  };
409
409
  const createMutation = (mutationFn, options = {}) => {
410
- const { onSuccess = floppyDisk.noop, onError, onSettled = floppyDisk.noop } = options;
410
+ const { onSuccess = vanilla.noop, onError, onSettled = vanilla.noop } = options;
411
411
  const initialState = INITIAL_STATE;
412
- const store = floppyDisk.initStore(initialState, options);
412
+ const store = vanilla.initStore(initialState, options);
413
413
  const useStore = (selector) => useStoreState(store, selector);
414
414
  const execute = (variable) => {
415
415
  const stateBeforeExecute = store.getState();
@@ -13,16 +13,16 @@ export type SetState<TState> = Partial<TState> | ((state: TState) => Partial<TSt
13
13
  * @param prevState - The previous state before the update
14
14
  *
15
15
  * @remarks
16
- * - Subscribers are always called on every `setState`, regardless of equality.
17
- * - It is the subscriber's responsibility to perform comparisons if needed.
16
+ * - Subscribers are only called when the state actually changes.
17
+ * - Change detection is performed per key using `Object.is`.
18
18
  */
19
19
  export type Subscriber<TState> = (state: TState, prevState: TState) => void;
20
20
  /**
21
21
  * Core store API for managing state.
22
22
  *
23
23
  * @remarks
24
- * - The store is intentionally simple and always notifies subscribers on updates.
25
- * - No internal equality checks are performed.
24
+ * - The store performs **shallow change detection per key** before notifying subscribers.
25
+ * - Subscribers are only notified when at least one field changes.
26
26
  * - Designed to be framework-agnostic (React bindings are built separately).
27
27
  */
28
28
  export type StoreApi<TState extends Record<string, any>> = {