floppy-disk 3.7.0 → 3.7.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.
@@ -1,4 +1,4 @@
1
- import { type InitStoreOptions, type StoreApi } from "../vanilla.mjs";
1
+ import { type InitStoreOptions, type SetStateInput } from "../vanilla.mjs";
2
2
  import type { StoreKey } from "./create-stores.mjs";
3
3
  type StreamDataState<TData, TError> = {
4
4
  state: "INITIAL";
@@ -43,8 +43,8 @@ export type StreamState<TData, TError> = ({
43
43
  }>) | ({
44
44
  connectionState: "CONNECTING";
45
45
  connectingAt: number;
46
- connectedAt: number | undefined;
47
- disconnectedAt: number | undefined;
46
+ connectedAt: undefined;
47
+ disconnectedAt: undefined;
48
48
  } & StreamDataState<TData, TError>) | ({
49
49
  connectionState: "CONNECTED";
50
50
  connectingAt: number;
@@ -68,6 +68,7 @@ type AdditionalStoreApi<TConnection> = {
68
68
  data: {
69
69
  reset: () => void;
70
70
  };
71
+ delete: () => boolean;
71
72
  };
72
73
  export type StreamOptions<TConnection, TData, TError = Error> = InitStoreOptions<StreamState<TData, TError>, AdditionalStoreApi<TConnection>> & {
73
74
  connection?: {
@@ -84,5 +85,20 @@ export declare const experimental_createStream: <TConnection, TData, TVariable e
84
85
  error: (error: TError) => void;
85
86
  }) => TConnection, disconnect: (connection: TConnection) => void, options?: StreamOptions<TConnection, TData, TError>) => (variable?: TVariable) => ((options?: {
86
87
  initialData?: TData;
87
- }) => StreamState<TData, TError>) & StoreApi<StreamState<TData, TError>> & AdditionalStoreApi<TConnection>;
88
+ }) => StreamState<TData, TError>) & {
89
+ setState: (value: SetStateInput<StreamState<TData, TError>>) => void;
90
+ getState: () => StreamState<TData, TError>;
91
+ subscribe: (subscriber: import("../vanilla.d.mts").Subscriber<StreamState<TData, TError>>) => () => void;
92
+ getSubscriberCount: () => number;
93
+ variableHash: string;
94
+ connection: {
95
+ get: () => Readonly<TConnection> | undefined;
96
+ reconnect: () => void;
97
+ disconnect: () => void;
98
+ };
99
+ data: {
100
+ reset: () => void;
101
+ };
102
+ delete: () => boolean;
103
+ };
88
104
  export {};
package/esm/react.mjs CHANGED
@@ -785,7 +785,20 @@ const experimental_createStream = (connect, disconnect, options = {}) => {
785
785
  const connections = /* @__PURE__ */ new WeakMap();
786
786
  const disconnectFns = /* @__PURE__ */ new WeakMap();
787
787
  const disconnectTimeoutIds = /* @__PURE__ */ new WeakMap();
788
- const clearDataTimeoutIds = /* @__PURE__ */ new WeakMap();
788
+ const clearAllTimeouts = (store) => {
789
+ const gcTimeoutId = gcTimeoutIds.get(store);
790
+ if (gcTimeoutId) {
791
+ clearTimeout(gcTimeoutId);
792
+ gcTimeoutIds.delete(store);
793
+ }
794
+ const disconnectTimeoutIds_ = disconnectTimeoutIds.get(store);
795
+ if (disconnectTimeoutIds_) {
796
+ clearTimeout(disconnectTimeoutIds_["last-unsubscribe"]);
797
+ clearTimeout(disconnectTimeoutIds_["document-hidden"]);
798
+ clearTimeout(disconnectTimeoutIds_.offline);
799
+ }
800
+ };
801
+ const gcTimeoutIds = /* @__PURE__ */ new WeakMap();
789
802
  const configureStoreEvents = () => ({
790
803
  ...options,
791
804
  onFirstSubscribe: (state, store) => {
@@ -827,12 +840,7 @@ const experimental_createStream = (connect, disconnect, options = {}) => {
827
840
  if (store.getSubscriberCount() && showLog) {
828
841
  console.log("Stream disconnected while there is subscriber");
829
842
  }
830
- const disconnectTimeoutIds_ = disconnectTimeoutIds.get(store);
831
- if (disconnectTimeoutIds_) {
832
- clearTimeout(disconnectTimeoutIds_["last-unsubscribe"]);
833
- clearTimeout(disconnectTimeoutIds_["document-hidden"]);
834
- clearTimeout(disconnectTimeoutIds_.offline);
835
- }
843
+ clearAllTimeouts(store);
836
844
  (_a = disconnectFns.get(store)) == null ? void 0 : _a();
837
845
  if (store.getState().connectionState !== "INITIAL") {
838
846
  store.setState({
@@ -842,10 +850,10 @@ const experimental_createStream = (connect, disconnect, options = {}) => {
842
850
  }
843
851
  connections.delete(store);
844
852
  disconnectFns.delete(store);
845
- clearDataTimeoutIds.set(
853
+ gcTimeoutIds.set(
846
854
  store,
847
855
  setTimeout(() => {
848
- store.data.reset();
856
+ if (store.getSubscriberCount() === 0) store.delete();
849
857
  }, gcTime)
850
858
  );
851
859
  };
@@ -866,12 +874,15 @@ const experimental_createStream = (connect, disconnect, options = {}) => {
866
874
  store.connection.get = () => connections.get(store);
867
875
  store.connection.reconnect = () => {
868
876
  var _a;
877
+ clearAllTimeouts(store);
869
878
  const { connectionState } = store.getState();
870
879
  if (connectionState === "CONNECTING") return;
871
880
  (_a = disconnectFns.get(store)) == null ? void 0 : _a();
872
881
  store.setState({
873
882
  connectionState: "CONNECTING",
874
- connectingAt: Date.now()
883
+ connectingAt: Date.now(),
884
+ connectedAt: void 0,
885
+ disconnectedAt: void 0
875
886
  });
876
887
  const connection = connect(variable, {
877
888
  connected: () => {
@@ -922,20 +933,31 @@ const experimental_createStream = (connect, disconnect, options = {}) => {
922
933
  errorUpdatedAt: void 0
923
934
  });
924
935
  };
936
+ store.delete = () => {
937
+ if (store.getSubscriberCount() > 0) {
938
+ console.warn(
939
+ "Cannot delete store while it still has active subscribers. Unsubscribe all listeners before deleting the store."
940
+ );
941
+ return false;
942
+ }
943
+ clearAllTimeouts(store);
944
+ store.setState(initialState);
945
+ return stores.delete(variableHash);
946
+ };
925
947
  }
926
948
  const useStore = (options2) => useStoreState(store, {
927
949
  initialState: { data: options2 == null ? void 0 : options2.initialData }
928
950
  });
929
- return Object.assign(useStore, store);
951
+ return Object.assign(useStore, {
952
+ ...store,
953
+ setState: (value) => {
954
+ console.debug("Manual setState (not via provided actions) on stream store");
955
+ store.setState(value);
956
+ }
957
+ });
930
958
  };
931
959
  const triggerReconnect = (store, trigger) => {
932
- clearTimeout(clearDataTimeoutIds.get(store));
933
- const disconnectTimeoutIds_ = disconnectTimeoutIds.get(store);
934
- if (disconnectTimeoutIds_) {
935
- clearTimeout(disconnectTimeoutIds_["last-unsubscribe"]);
936
- clearTimeout(disconnectTimeoutIds_["document-hidden"]);
937
- clearTimeout(disconnectTimeoutIds_.offline);
938
- }
960
+ clearAllTimeouts(store);
939
961
  const { connectionState } = store.getState();
940
962
  if (connectionState === "INITIAL" || connectionState === "DISCONNECTED") {
941
963
  return store.connection.reconnect();
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "floppy-disk",
3
3
  "description": "Lightweight unified state management for sync and async data.",
4
4
  "private": false,
5
- "version": "3.7.0",
5
+ "version": "3.7.1",
6
6
  "keywords": [
7
7
  "utilities",
8
8
  "store",
@@ -1,4 +1,4 @@
1
- import { type InitStoreOptions, type StoreApi } from "../vanilla.ts";
1
+ import { type InitStoreOptions, type SetStateInput } from "../vanilla.ts";
2
2
  import type { StoreKey } from "./create-stores.ts";
3
3
  type StreamDataState<TData, TError> = {
4
4
  state: "INITIAL";
@@ -43,8 +43,8 @@ export type StreamState<TData, TError> = ({
43
43
  }>) | ({
44
44
  connectionState: "CONNECTING";
45
45
  connectingAt: number;
46
- connectedAt: number | undefined;
47
- disconnectedAt: number | undefined;
46
+ connectedAt: undefined;
47
+ disconnectedAt: undefined;
48
48
  } & StreamDataState<TData, TError>) | ({
49
49
  connectionState: "CONNECTED";
50
50
  connectingAt: number;
@@ -68,6 +68,7 @@ type AdditionalStoreApi<TConnection> = {
68
68
  data: {
69
69
  reset: () => void;
70
70
  };
71
+ delete: () => boolean;
71
72
  };
72
73
  export type StreamOptions<TConnection, TData, TError = Error> = InitStoreOptions<StreamState<TData, TError>, AdditionalStoreApi<TConnection>> & {
73
74
  connection?: {
@@ -84,5 +85,20 @@ export declare const experimental_createStream: <TConnection, TData, TVariable e
84
85
  error: (error: TError) => void;
85
86
  }) => TConnection, disconnect: (connection: TConnection) => void, options?: StreamOptions<TConnection, TData, TError>) => (variable?: TVariable) => ((options?: {
86
87
  initialData?: TData;
87
- }) => StreamState<TData, TError>) & StoreApi<StreamState<TData, TError>> & AdditionalStoreApi<TConnection>;
88
+ }) => StreamState<TData, TError>) & {
89
+ setState: (value: SetStateInput<StreamState<TData, TError>>) => void;
90
+ getState: () => StreamState<TData, TError>;
91
+ subscribe: (subscriber: import("../vanilla.ts").Subscriber<StreamState<TData, TError>>) => () => void;
92
+ getSubscriberCount: () => number;
93
+ variableHash: string;
94
+ connection: {
95
+ get: () => Readonly<TConnection> | undefined;
96
+ reconnect: () => void;
97
+ disconnect: () => void;
98
+ };
99
+ data: {
100
+ reset: () => void;
101
+ };
102
+ delete: () => boolean;
103
+ };
88
104
  export {};
package/react.js CHANGED
@@ -787,7 +787,20 @@ const experimental_createStream = (connect, disconnect, options = {}) => {
787
787
  const connections = /* @__PURE__ */ new WeakMap();
788
788
  const disconnectFns = /* @__PURE__ */ new WeakMap();
789
789
  const disconnectTimeoutIds = /* @__PURE__ */ new WeakMap();
790
- const clearDataTimeoutIds = /* @__PURE__ */ new WeakMap();
790
+ const clearAllTimeouts = (store) => {
791
+ const gcTimeoutId = gcTimeoutIds.get(store);
792
+ if (gcTimeoutId) {
793
+ clearTimeout(gcTimeoutId);
794
+ gcTimeoutIds.delete(store);
795
+ }
796
+ const disconnectTimeoutIds_ = disconnectTimeoutIds.get(store);
797
+ if (disconnectTimeoutIds_) {
798
+ clearTimeout(disconnectTimeoutIds_["last-unsubscribe"]);
799
+ clearTimeout(disconnectTimeoutIds_["document-hidden"]);
800
+ clearTimeout(disconnectTimeoutIds_.offline);
801
+ }
802
+ };
803
+ const gcTimeoutIds = /* @__PURE__ */ new WeakMap();
791
804
  const configureStoreEvents = () => ({
792
805
  ...options,
793
806
  onFirstSubscribe: (state, store) => {
@@ -829,12 +842,7 @@ const experimental_createStream = (connect, disconnect, options = {}) => {
829
842
  if (store.getSubscriberCount() && showLog) {
830
843
  console.log("Stream disconnected while there is subscriber");
831
844
  }
832
- const disconnectTimeoutIds_ = disconnectTimeoutIds.get(store);
833
- if (disconnectTimeoutIds_) {
834
- clearTimeout(disconnectTimeoutIds_["last-unsubscribe"]);
835
- clearTimeout(disconnectTimeoutIds_["document-hidden"]);
836
- clearTimeout(disconnectTimeoutIds_.offline);
837
- }
845
+ clearAllTimeouts(store);
838
846
  (_a = disconnectFns.get(store)) == null ? void 0 : _a();
839
847
  if (store.getState().connectionState !== "INITIAL") {
840
848
  store.setState({
@@ -844,10 +852,10 @@ const experimental_createStream = (connect, disconnect, options = {}) => {
844
852
  }
845
853
  connections.delete(store);
846
854
  disconnectFns.delete(store);
847
- clearDataTimeoutIds.set(
855
+ gcTimeoutIds.set(
848
856
  store,
849
857
  setTimeout(() => {
850
- store.data.reset();
858
+ if (store.getSubscriberCount() === 0) store.delete();
851
859
  }, gcTime)
852
860
  );
853
861
  };
@@ -868,12 +876,15 @@ const experimental_createStream = (connect, disconnect, options = {}) => {
868
876
  store.connection.get = () => connections.get(store);
869
877
  store.connection.reconnect = () => {
870
878
  var _a;
879
+ clearAllTimeouts(store);
871
880
  const { connectionState } = store.getState();
872
881
  if (connectionState === "CONNECTING") return;
873
882
  (_a = disconnectFns.get(store)) == null ? void 0 : _a();
874
883
  store.setState({
875
884
  connectionState: "CONNECTING",
876
- connectingAt: Date.now()
885
+ connectingAt: Date.now(),
886
+ connectedAt: void 0,
887
+ disconnectedAt: void 0
877
888
  });
878
889
  const connection = connect(variable, {
879
890
  connected: () => {
@@ -924,20 +935,31 @@ const experimental_createStream = (connect, disconnect, options = {}) => {
924
935
  errorUpdatedAt: void 0
925
936
  });
926
937
  };
938
+ store.delete = () => {
939
+ if (store.getSubscriberCount() > 0) {
940
+ console.warn(
941
+ "Cannot delete store while it still has active subscribers. Unsubscribe all listeners before deleting the store."
942
+ );
943
+ return false;
944
+ }
945
+ clearAllTimeouts(store);
946
+ store.setState(initialState);
947
+ return stores.delete(variableHash);
948
+ };
927
949
  }
928
950
  const useStore = (options2) => useStoreState(store, {
929
951
  initialState: { data: options2 == null ? void 0 : options2.initialData }
930
952
  });
931
- return Object.assign(useStore, store);
953
+ return Object.assign(useStore, {
954
+ ...store,
955
+ setState: (value) => {
956
+ console.debug("Manual setState (not via provided actions) on stream store");
957
+ store.setState(value);
958
+ }
959
+ });
932
960
  };
933
961
  const triggerReconnect = (store, trigger) => {
934
- clearTimeout(clearDataTimeoutIds.get(store));
935
- const disconnectTimeoutIds_ = disconnectTimeoutIds.get(store);
936
- if (disconnectTimeoutIds_) {
937
- clearTimeout(disconnectTimeoutIds_["last-unsubscribe"]);
938
- clearTimeout(disconnectTimeoutIds_["document-hidden"]);
939
- clearTimeout(disconnectTimeoutIds_.offline);
940
- }
962
+ clearAllTimeouts(store);
941
963
  const { connectionState } = store.getState();
942
964
  if (connectionState === "INITIAL" || connectionState === "DISCONNECTED") {
943
965
  return store.connection.reconnect();