hermes-io 2.11.95 → 2.12.97

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.
@@ -0,0 +1,11 @@
1
+ import { ComponentType } from "react";
2
+ import type { Context } from "../../context/context";
3
+ import type { Observer } from "../../observer/observer";
4
+ interface WithNotifyConfig {
5
+ context: Context;
6
+ observer: Observer;
7
+ }
8
+ export declare function withNotify<P extends Record<string, unknown>>(Component: ComponentType<P & {
9
+ notify: (value: unknown) => Promise<unknown>;
10
+ }>, { context, observer }: WithNotifyConfig): (props: P) => import("react/jsx-runtime").JSX.Element;
11
+ export {};
@@ -1 +1,5 @@
1
- function _extends(){return(_extends=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var n=arguments[e];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(t[r]=n[r])}return t}).apply(this,arguments)}import t from"react";export function withNotify(e,n){var r=n.context,o=n.observer,i=function(t){return o.notify({context:r,value:t})};return function(n){return t.createElement(e,_extends({notify:i},n))}}
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ export function withNotify(Component, { context, observer }) {
3
+ const notify = (value) => observer.notify({ context, value });
4
+ return (props) => _jsx(Component, { notify: notify, ...props });
5
+ }
@@ -0,0 +1,10 @@
1
+ declare const CONSTANTS: {
2
+ readonly CHROME_EXTENSION: "hermes-io-devtools";
3
+ readonly CONTEXT_SNAPSHOT: "CONTEXT_SNAPSHOT";
4
+ readonly START_RECORDING: "START_RECORDING";
5
+ readonly STOP_RECORDING: "STOP_RECORDING";
6
+ readonly SET_CONTEXT: "SET_CONTEXT";
7
+ readonly LOAD_RECORDING: "LOAD_RECORDING";
8
+ readonly RESET_RECORDING: "RESET_RECORDING";
9
+ };
10
+ export default CONSTANTS;
package/lib/constants.js CHANGED
@@ -1 +1,10 @@
1
- export default{CHROME_EXTENSION:"hermes-io-devtools",CONTEXT_SNAPSHOT:"CONTEXT_SNAPSHOT",START_RECORDING:"START_RECORDING",STOP_RECORDING:"STOP_RECORDING",SET_CONTEXT:"SET_CONTEXT",LOAD_RECORDING:"LOAD_RECORDING",RESET_RECORDING:"RESET_RECORDING"};
1
+ const CONSTANTS = {
2
+ CHROME_EXTENSION: "hermes-io-devtools",
3
+ CONTEXT_SNAPSHOT: "CONTEXT_SNAPSHOT",
4
+ START_RECORDING: "START_RECORDING",
5
+ STOP_RECORDING: "STOP_RECORDING",
6
+ SET_CONTEXT: "SET_CONTEXT",
7
+ LOAD_RECORDING: "LOAD_RECORDING",
8
+ RESET_RECORDING: "RESET_RECORDING",
9
+ };
10
+ export default CONSTANTS;
@@ -0,0 +1,29 @@
1
+ interface SnapshotItem {
2
+ _internalId: string;
3
+ value: unknown;
4
+ date: Date | null;
5
+ listener: ((...args: unknown[]) => unknown) | null;
6
+ stackTrace: string | undefined;
7
+ isFromExternalRecording?: boolean;
8
+ id?: string;
9
+ }
10
+ export declare const listenersMap: Map<string, (...args: unknown[]) => unknown>;
11
+ export declare function subscribeDevtools(): void;
12
+ export declare function unsubscribeDevtools(): void;
13
+ export declare class Context {
14
+ id: symbol;
15
+ _internalId: string | null;
16
+ date: Date | null;
17
+ value: unknown;
18
+ listener: ((...args: unknown[]) => unknown) | null;
19
+ stackTrace: string | undefined;
20
+ constructor(description: string);
21
+ update: ({ value, listener }: {
22
+ value: unknown;
23
+ listener: (...args: unknown[]) => unknown;
24
+ }) => void;
25
+ sendSnapshot: () => void;
26
+ takeSnapshot: () => SnapshotItem;
27
+ getStackTrace: () => string | undefined;
28
+ }
29
+ export {};
@@ -1 +1,120 @@
1
- function _extends(){return(_extends=Object.assign||function(e){for(var n=1;n<arguments.length;n++){var t=arguments[n];for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r])}return e}).apply(this,arguments)}import e from"../constants.js";var _obj,recording=!1,collection=[];export var listenersMap=new Map;var actions=((_obj={})[e.START_RECORDING]=function(){recording=!0},_obj[e.STOP_RECORDING]=function(){recording=!1},_obj[e.RESET_RECORDING]=function(){collection=[],recording=!1},_obj[e.SET_CONTEXT]=function(e){var n=e.id,t=void 0===n?"":n,r=collection.find(function(e){return e._internalId===t});if(r){if(r.isFromExternalRecording){var i=listenersMap.get(r.listener);return null==i?void 0:i({value:JSON.parse(r.value)})}return r.listener(r.value)}},_obj[e.LOAD_RECORDING]=function(e){collection=e.recording.map(function(e){return void 0===e&&(e={}),_extends({},e,{isFromExternalRecording:!0,_internalId:e.id})})},_obj);"undefined"!=typeof window&&window.addEventListener("message",function(n){try{var t=n.data,r=t.source,i=t.payload;if(r===e.CHROME_EXTENSION){if(null==i?void 0:i.type)return actions[i.type](i);actions[i]()}}catch(e){console.error(e)}});export var Context=function(n){var t=this;this.id=null,this._internalId=null,this.date=null,this.value=null,this.listener=null,this.stackTrace=null,this.update=function(e){var n=e.value,r=e.listener;t.date=new Date,t.value=n,t.stackTrace=t.getStackTrace(),t.listener=r,recording&&t.sendSnapshot()},this.sendSnapshot=function(){var n=t.takeSnapshot(),r=n.listener,i=n.stackTrace,a=n.value,o=n.date,s=n._internalId;collection.push(n),"undefined"!=typeof window&&window.postMessage({type:e.CONTEXT_SNAPSHOT,payload:{value:JSON.stringify(a.value),listener:r.name,stackTrace:i,date:o,id:s},source:"hermes-io"},"*")},this.takeSnapshot=function(){return{_internalId:crypto.randomUUID(),value:t.value,date:t.date,listener:t.listener,stackTrace:t.stackTrace}},this.getStackTrace=function(){return Error().stack},this.id=Symbol(n)};
1
+ import CONSTANTS from "../constants";
2
+ let recording = false;
3
+ let collection = [];
4
+ export const listenersMap = new Map();
5
+ function startRecording() {
6
+ recording = true;
7
+ }
8
+ function stopRecording() {
9
+ recording = false;
10
+ }
11
+ function resetRecording() {
12
+ collection = [];
13
+ recording = false;
14
+ }
15
+ function setContext({ id = "" }) {
16
+ const context = collection.find((context) => context._internalId === id);
17
+ if (context) {
18
+ if (context.isFromExternalRecording) {
19
+ const listener = listenersMap.get(context.listener);
20
+ listener?.({ value: JSON.parse(context.value) });
21
+ return;
22
+ }
23
+ context.listener?.(context.value);
24
+ }
25
+ }
26
+ function loadRecording(payload) {
27
+ collection = (payload.recording ?? []).map((item = {}) => ({
28
+ ...item,
29
+ isFromExternalRecording: true,
30
+ _internalId: item.id,
31
+ }));
32
+ }
33
+ const actions = {
34
+ [CONSTANTS.START_RECORDING]: startRecording,
35
+ [CONSTANTS.STOP_RECORDING]: stopRecording,
36
+ [CONSTANTS.RESET_RECORDING]: resetRecording,
37
+ [CONSTANTS.SET_CONTEXT]: setContext,
38
+ [CONSTANTS.LOAD_RECORDING]: loadRecording,
39
+ };
40
+ const handleMessageFromDevtools = (event) => {
41
+ try {
42
+ if (event.origin !== window.location.origin)
43
+ return;
44
+ const { source, payload } = event.data;
45
+ if (source === CONSTANTS.CHROME_EXTENSION) {
46
+ if (payload?.type) {
47
+ actions[payload.type]?.(payload);
48
+ return;
49
+ }
50
+ actions[payload]?.();
51
+ }
52
+ }
53
+ catch (error) {
54
+ console.error(error);
55
+ }
56
+ };
57
+ let listenerRegistered = false;
58
+ export function subscribeDevtools() {
59
+ if (typeof window === "undefined" || listenerRegistered)
60
+ return;
61
+ listenerRegistered = true;
62
+ window.addEventListener("message", handleMessageFromDevtools);
63
+ }
64
+ export function unsubscribeDevtools() {
65
+ if (typeof window === "undefined" || !listenerRegistered)
66
+ return;
67
+ listenerRegistered = false;
68
+ window.removeEventListener("message", handleMessageFromDevtools);
69
+ }
70
+ subscribeDevtools();
71
+ export class Context {
72
+ constructor(description) {
73
+ this._internalId = null;
74
+ this.date = null;
75
+ this.value = null;
76
+ this.listener = null;
77
+ this.stackTrace = undefined;
78
+ this.update = ({ value, listener }) => {
79
+ this.date = new Date();
80
+ this.value = value;
81
+ this.stackTrace = this.getStackTrace();
82
+ this.listener = listener;
83
+ if (recording) {
84
+ this.sendSnapshot();
85
+ }
86
+ };
87
+ this.sendSnapshot = () => {
88
+ const snapshot = this.takeSnapshot();
89
+ const { listener, stackTrace, value, date, _internalId } = snapshot;
90
+ collection.push(snapshot);
91
+ if (typeof window !== "undefined") {
92
+ window.postMessage({
93
+ type: CONSTANTS.CONTEXT_SNAPSHOT,
94
+ payload: {
95
+ value: JSON.stringify(value?.value),
96
+ listener: listener?.name,
97
+ stackTrace,
98
+ date,
99
+ id: _internalId,
100
+ },
101
+ source: "hermes-io",
102
+ }, window.location.origin);
103
+ }
104
+ };
105
+ this.takeSnapshot = () => {
106
+ return {
107
+ _internalId: crypto.randomUUID(),
108
+ value: this.value,
109
+ date: this.date,
110
+ listener: this.listener,
111
+ stackTrace: this.stackTrace,
112
+ };
113
+ };
114
+ this.getStackTrace = () => {
115
+ const err = new Error();
116
+ return err.stack;
117
+ };
118
+ this.id = Symbol(description);
119
+ }
120
+ }
@@ -0,0 +1,3 @@
1
+ export * from './useObserver';
2
+ export * from './useMutations';
3
+ export * from './useStore';
@@ -1 +1,3 @@
1
- export*from"./useObserver.js";export*from"./useMutations.js";export*from"./useStore.js";export*from"./useObservableStore.js";
1
+ export * from './useObserver';
2
+ export * from './useMutations';
3
+ export * from './useStore';
@@ -0,0 +1,23 @@
1
+ import type { Store } from "../store/store";
2
+ type OnChangeCallback = (value: unknown, resolver: (value?: unknown) => void, setNoUpdate: (value: boolean) => void, prevState: Record<string, unknown>) => Record<string, unknown> | void;
3
+ interface CustomEvent {
4
+ event: string;
5
+ onChange: OnChangeCallback;
6
+ }
7
+ interface MutationRef {
8
+ id: string;
9
+ state: Record<string, unknown>;
10
+ events: CustomEvent[];
11
+ onEvent: (event: string, onChange: OnChangeCallback) => void;
12
+ }
13
+ export interface UseMutationsProps {
14
+ events?: string[];
15
+ onChange?: OnChangeCallback;
16
+ store?: Store;
17
+ id?: string;
18
+ initialState?: Record<string, unknown>;
19
+ name?: string;
20
+ noUpdate?: boolean;
21
+ }
22
+ export declare const useMutations: (props?: UseMutationsProps) => MutationRef;
23
+ export {};
@@ -1 +1,93 @@
1
- function _array_like_to_array(e,r){(null==r||r>e.length)&&(r=e.length);for(var t=0,n=Array(r);t<r;t++)n[t]=e[t];return n}function _extends(){return(_extends=Object.assign||function(e){for(var r=1;r<arguments.length;r++){var t=arguments[r];for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])}return e}).apply(this,arguments)}function _create_for_of_iterator_helper_loose(e,r){var t="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(t)return(t=t.call(e)).next.bind(t);if(Array.isArray(e)||(t=function(e,r){if(e){if("string"==typeof e)return _array_like_to_array(e,void 0);var t=Object.prototype.toString.call(e).slice(8,-1);if("Object"===t&&e.constructor&&(t=e.constructor.name),"Map"===t||"Set"===t)return Array.from(t);if("Arguments"===t||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t))return _array_like_to_array(e,void 0)}}(e))||r&&e&&"number"==typeof e.length){t&&(e=t);var n=0;return function(){return n>=e.length?{done:!0}:{done:!1,value:e[n++]}}}throw TypeError("Invalid attempt to iterate non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}import{useState as e,useEffect as r,useRef as t,useCallback as n}from"react";import{useObserver as o}from"./useObserver.js";import{MicroStore as a}from"../store/store.js";import{getStackTrace as i,randomId as l}from"../utils.js";export var useMutations=function(u){void 0===u&&(u={});var s,v=u.events,c=void 0===v?[]:v,f=u.onChange,d=u.store,_=u.id,p=u.initialState,y=u.name,m=void 0===y?"":y,h=e(l()),b=(h[0],h[1]),g=t({id:i()+"_"+(null!=_?_:""),state:_extends({},void 0===p?{}:p),events:[],onEvent:function(e,r){var t=g.current.events;t.some(function(r){return r.event===e})||t.push({event:e,onChange:r})}}),S=function(e){return u.noUpdate=e},x=function(e,r,t,n){var o=!e,a=!1;if(null==e||null==(i=e.forEach)||i.call(e,function(e){if(e===u.id){a=!0;var o,i=null!=(o=null==n?void 0:n(r,t,S,g.current.state))?o:{};u.noUpdate&&(i={}),g.current.state=_extends({},g.current.state,i)}}),o){var i,s,v=null!=(s=null==n?void 0:n(r,t,S,g.current.state))?s:{};u.noUpdate&&(v={}),g.current.state=_extends({},g.current.state,v)}!0!==u.noUpdate&&!1!==a&&b(l())},j=n(function(e,r){var t=null==(i=e.value)?void 0:null==(a=i.payload)?void 0:a.value,n=null==(l=e.value)?void 0:l.targets,o=null==(u=g.current)?void 0:u.events;if(o.length>0){for(var a,i,l,u,s,v=_create_for_of_iterator_helper_loose(o);!(s=v()).done;){var d=s.value;e.value.type===d.event&&x(n,t,r,d.onChange)}return}for(var _,p=_create_for_of_iterator_helper_loose(c);!(_=p()).done;){var y=_.value;e.value.type===y&&x(n,t,r,f)}},[c,null==(s=g.current)?void 0:s.events]);return r(function(){var e=null!=a&&"undefined"!=typeof Symbol&&a[Symbol.hasInstance]?!!a[Symbol.hasInstance](d):d instanceof a;if(e){var r=g.current.id;j.id=r;var t=d.has(_);d.hasListener(r)||d.registerListener(_,j),t&&!d.get(_).observer.has(r)&&d.subscribeStore(_,d.get(_),m)}return function(){e&&d.remove(_,g.current.id)}},[]),o({store:d,listener:j,contexts:[null==d?void 0:d.context],observer:null==d?void 0:d.observer}),g.current};
1
+ import { useState, useEffect, useRef, useCallback } from "react";
2
+ import { useObserver } from "./useObserver";
3
+ import { MicroStore } from "../store/store";
4
+ import { getStackTrace, randomId } from "../utils";
5
+ export const useMutations = (props = {}) => {
6
+ const { events = [], onChange, store, id, initialState = {}, name = "", noUpdate: initialNoUpdate, } = props;
7
+ const [_renderId, setReRenderId] = useState(randomId());
8
+ const noUpdateRef = useRef(initialNoUpdate);
9
+ const mutationRef = useRef({
10
+ id: `${getStackTrace()}_${id ?? ""}`,
11
+ state: { ...initialState },
12
+ events: [],
13
+ onEvent: (event, onChange) => {
14
+ const events = mutationRef.current.events;
15
+ const isAlreadyIn = events.some((item) => item.event === event);
16
+ if (!isAlreadyIn)
17
+ events.push({ event, onChange });
18
+ },
19
+ });
20
+ const setNoUpdate = (value) => {
21
+ noUpdateRef.current = value;
22
+ };
23
+ const executeEvent = (targets, value, resolver, onChange) => {
24
+ const hasNotTargets = !targets;
25
+ let match = false;
26
+ targets?.forEach?.((target) => {
27
+ if (target === id) {
28
+ match = true;
29
+ let result = onChange?.(value, resolver, setNoUpdate, mutationRef.current.state) ??
30
+ {};
31
+ if (noUpdateRef.current)
32
+ result = {};
33
+ mutationRef.current.state = { ...mutationRef.current.state, ...result };
34
+ }
35
+ });
36
+ if (hasNotTargets) {
37
+ let result = onChange?.(value, resolver, setNoUpdate, mutationRef.current.state) ??
38
+ {};
39
+ if (noUpdateRef.current)
40
+ result = {};
41
+ mutationRef.current.state = { ...mutationRef.current.state, ...result };
42
+ }
43
+ if (noUpdateRef.current === true || match === false)
44
+ return;
45
+ setReRenderId(randomId());
46
+ };
47
+ const handleNotification = useCallback(((e, resolver) => {
48
+ const payload = e.value?.payload;
49
+ const value = payload?.value;
50
+ const targets = e.value?.targets;
51
+ const customs = mutationRef.current?.events;
52
+ const hasCustomEvents = customs.length > 0;
53
+ if (hasCustomEvents) {
54
+ for (const custom of customs) {
55
+ if (e.value.type !== custom.event)
56
+ continue;
57
+ executeEvent(targets, value, resolver, custom.onChange);
58
+ }
59
+ return;
60
+ }
61
+ for (const event of events) {
62
+ if (e.value.type !== event)
63
+ continue;
64
+ executeEvent(targets, value, resolver, onChange);
65
+ }
66
+ }), [events, mutationRef.current?.events]);
67
+ useEffect(() => {
68
+ const isMicroStore = store instanceof MicroStore;
69
+ if (isMicroStore) {
70
+ const microStore = store;
71
+ const { id: mutationId } = mutationRef.current;
72
+ handleNotification.id = mutationId;
73
+ const isPopulated = microStore.has(id);
74
+ if (!microStore.hasListener(mutationId)) {
75
+ microStore.registerListener(id, handleNotification);
76
+ }
77
+ if (isPopulated && !microStore.get(id).observer.has(mutationId)) {
78
+ microStore.subscribeStore(id, microStore.get(id));
79
+ }
80
+ }
81
+ return () => {
82
+ if (isMicroStore)
83
+ store.remove(id, mutationRef.current.id);
84
+ };
85
+ }, []);
86
+ useObserver({
87
+ store,
88
+ listener: handleNotification,
89
+ contexts: store?.context ? [store.context] : [],
90
+ observer: store?.observer,
91
+ });
92
+ return mutationRef.current;
93
+ };
@@ -0,0 +1,11 @@
1
+ import { Store } from "../store/store";
2
+ import type { Context } from "../context/context";
3
+ import type { Observer, Subscriber } from "../observer/observer";
4
+ export declare const hasValidList: (contexts: Context[] | undefined, payload: Record<string, unknown>) => Context | undefined;
5
+ export interface UseObserverProps {
6
+ store?: Store;
7
+ listener?: Subscriber;
8
+ contexts?: Context[];
9
+ observer?: Observer;
10
+ }
11
+ export declare const useObserver: (props: UseObserverProps) => void;
@@ -1 +1,25 @@
1
- import{useEffect as n}from"react";import{Store as l}from"../store/store.js";export var hasValidList=function(n,l){var e;return void 0===n&&(n=[]),null==n?void 0:null==(e=n.find)?void 0:e.call(n,function(n){var e;return n.id===(null==l?void 0:null==(e=l.context)?void 0:e.id)})};export var useObserver=function(e){n(function(){var n,r,t=function(n,l){var e;hasValidList(u,n)&&(null==n||null==(e=n.context)||e.update({value:n,listener:o}),null==o||o(n,l))},o=e.listener,i=e.observer,u=e.contexts,s=(n=e.store,null!=l&&"undefined"!=typeof Symbol&&l[Symbol.hasInstance]?!!l[Symbol.hasInstance](n):n instanceof l);return s&&(null==i||null==(r=i.subscribe)||r.call(i,t)),function(){var n;return s&&(null==i?void 0:null==(n=i.unsubscribe)?void 0:n.call(i,t))}},[e.listener,e.observer,e.contexts])};
1
+ import { useEffect } from "react";
2
+ import { Store } from "../store/store";
3
+ export const hasValidList = (contexts = [], payload) => contexts?.find?.((ctx) => ctx.id === payload?.context?.id);
4
+ export const useObserver = (props) => {
5
+ useEffect(() => {
6
+ const { listener, observer, contexts, store } = props;
7
+ const isStore = store instanceof Store;
8
+ const subscriber = function (payload, resolve) {
9
+ if (!hasValidList(contexts, payload))
10
+ return;
11
+ payload?.context &&
12
+ payload.context.update?.({
13
+ value: payload,
14
+ listener: listener,
15
+ });
16
+ listener?.(payload, resolve);
17
+ };
18
+ if (isStore)
19
+ observer?.subscribe?.(subscriber);
20
+ return () => {
21
+ if (isStore)
22
+ observer?.unsubscribe?.(subscriber);
23
+ };
24
+ }, [props.listener, props.observer, props.contexts]);
25
+ };
@@ -0,0 +1,22 @@
1
+ import type { Store } from "../store/store";
2
+ import type { MicroStore } from "../store/store";
3
+ export interface UseStoreProps {
4
+ store: Store;
5
+ reducer: (state: unknown, action: {
6
+ type: string;
7
+ payload?: unknown;
8
+ }) => unknown;
9
+ data?: unknown;
10
+ microStore?: MicroStore;
11
+ id?: string;
12
+ name?: string;
13
+ }
14
+ export declare function useStore(props: UseStoreProps): {
15
+ query: (cb: (store: Store) => unknown, defaultValue?: unknown) => unknown;
16
+ mutate: ({ type, payload, targets }: {
17
+ type: string;
18
+ payload?: unknown;
19
+ targets?: string[];
20
+ }) => Promise<unknown>;
21
+ store: Store;
22
+ };
@@ -1 +1,24 @@
1
- import{useCallback as t,useRef as r}from"react";import{useMicroStore as e}from"./useMicroStore";export function useStore(a){var o=a.name,u=a.reducer,n=a.data,i=a.microStore,s=a.id,m=r(a.store).current,c=m.mutate=t(function(t){var r=t.type,e=t.payload,a=t.targets,o=u(m.state,{type:r,payload:e});return m.notify({type:r,payload:e,state:o,targets:a})},[]),p=m.query=t(function(t,r){var e;return null!=(e=t(m))?e:r},[]);return m.state||(m.state=n),e({id:s,microStore:i,store:m,name:o}),{query:p,mutate:c,store:m}}
1
+ import { useCallback, useEffect, useRef } from "react";
2
+ export function useStore(props) {
3
+ const { name, reducer, data, microStore, id } = props;
4
+ const storeRef = useRef(props.store);
5
+ const store = storeRef.current;
6
+ const reducerRef = useRef(reducer);
7
+ reducerRef.current = reducer;
8
+ const mutate = (store.mutate = useCallback(({ type, payload, targets }) => {
9
+ const newState = reducerRef.current(store.state, { type, payload });
10
+ return store.notify({ type, payload, state: newState, targets });
11
+ }, [store]));
12
+ const query = (store.query = useCallback((cb, defaultValue) => cb(store) ?? defaultValue, [store]));
13
+ if (!store.state)
14
+ store.state = data;
15
+ useEffect(() => {
16
+ if (!id || !microStore || microStore.has?.(id))
17
+ return;
18
+ microStore.add?.(id, store, name);
19
+ return () => {
20
+ microStore.removeAll?.(id);
21
+ };
22
+ }, [microStore, store, id]);
23
+ return { query, mutate, store };
24
+ }
package/lib/index.d.ts ADDED
@@ -0,0 +1,5 @@
1
+ export * from "./hooks/index";
2
+ export * from "./observer/observer";
3
+ export * from "./context/context";
4
+ export * from "./store/store";
5
+ export * from "./components/withNotify/withNotify";
package/lib/index.js CHANGED
@@ -1 +1,5 @@
1
- export*from"./hooks/index.js";export*from"./observer/observer.js";export*from"./context/context.js";export*from"./store/store.js";export*from"./components/withNotify/withNotify.js";
1
+ export * from "./hooks/index";
2
+ export * from "./observer/observer";
3
+ export * from "./context/context";
4
+ export * from "./store/store";
5
+ export * from "./components/withNotify/withNotify";
@@ -0,0 +1,14 @@
1
+ export type Subscriber = {
2
+ (args: Record<string, unknown>, resolve: (value?: unknown) => void): void;
3
+ id?: string;
4
+ };
5
+ export interface NotifyOptions {
6
+ timeout?: number;
7
+ }
8
+ export declare class Observer {
9
+ subscriptors: Subscriber[];
10
+ subscribe(callback: Subscriber): void;
11
+ unsubscribe(callback: Subscriber): void;
12
+ has: (id: string) => boolean;
13
+ notify(args?: Record<string, unknown>, { timeout }?: NotifyOptions): Promise<unknown>;
14
+ }
@@ -1 +1,25 @@
1
- export var Observer=function(){function r(){var r=this;this.subscriptors=[],this.has=function(s){return r.subscriptors.some(function(r){return s===r.id})}}var s=r.prototype;return s.subscribe=function(r){this.subscriptors.push(r)},s.unsubscribe=function(r){this.subscriptors.splice(this.subscriptors.findIndex(function(s){return s===r}),1)},s.notify=function(r){var s=this;return void 0===r&&(r={}),new Promise(function(t){s.subscriptors.forEach(function(s){return s(r,t)})})},r}();
1
+ export class Observer {
2
+ constructor() {
3
+ this.subscriptors = [];
4
+ this.has = (id) => this.subscriptors.some((subscriber) => id === subscriber.id);
5
+ }
6
+ subscribe(callback) {
7
+ this.subscriptors.push(callback);
8
+ }
9
+ unsubscribe(callback) {
10
+ const index = this.subscriptors.findIndex((cb) => cb === callback);
11
+ if (index > -1)
12
+ this.subscriptors.splice(index, 1);
13
+ }
14
+ notify(args = {}, { timeout = 30000 } = {}) {
15
+ return new Promise((resolve) => {
16
+ const timer = timeout > 0 ? setTimeout(() => resolve(null), timeout) : null;
17
+ const wrappedResolve = (value) => {
18
+ if (timer)
19
+ clearTimeout(timer);
20
+ resolve(value);
21
+ };
22
+ this.subscriptors.forEach((callback) => callback(args, wrappedResolve));
23
+ });
24
+ }
25
+ }
@@ -0,0 +1,34 @@
1
+ import type { Observer, Subscriber } from "../observer/observer";
2
+ import type { Context } from "../context/context";
3
+ export interface StoreConfig {
4
+ context: Context;
5
+ observer: Observer;
6
+ id?: string;
7
+ }
8
+ export declare class Store {
9
+ context: Context;
10
+ observer: Observer;
11
+ id: string | undefined;
12
+ state: unknown;
13
+ constructor({ context, observer, id }: StoreConfig);
14
+ notify: (value: Record<string, unknown>) => Promise<unknown>;
15
+ query: (cb: (store: Store) => unknown, defaultValue?: unknown) => unknown;
16
+ mutate: (action: {
17
+ type: string;
18
+ payload?: unknown;
19
+ targets?: string[];
20
+ }) => unknown;
21
+ }
22
+ export type ListenerCallback = Subscriber;
23
+ export declare class MicroStore {
24
+ collection: Map<string, Store>;
25
+ listeners: Map<string, Subscriber[]>;
26
+ subscribeStore: (id: string, store: Store) => void;
27
+ add: (id: string, store: Store, _name?: string) => Store;
28
+ registerListener: (id: string, cb: ListenerCallback) => void;
29
+ hasListener: (id: string) => boolean;
30
+ remove: (id: string, mutationId: string) => void;
31
+ removeAll: (id: string) => void;
32
+ get: (id: string) => Store | undefined;
33
+ has: (id: string) => boolean;
34
+ }
@@ -1 +1,95 @@
1
- function _array_like_to_array(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,o=Array(t);r<t;r++)o[r]=e[r];return o}function _create_for_of_iterator_helper_loose(e,t){var r="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(r)return(r=r.call(e)).next.bind(r);if(Array.isArray(e)||(r=function(e,t){if(e){if("string"==typeof e)return _array_like_to_array(e,void 0);var r=Object.prototype.toString.call(e).slice(8,-1);if("Object"===r&&e.constructor&&(r=e.constructor.name),"Map"===r||"Set"===r)return Array.from(r);if("Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r))return _array_like_to_array(e,void 0)}}(e))||t&&e&&"number"==typeof e.length){r&&(e=r);var o=0;return function(){return o>=e.length?{done:!0}:{done:!1,value:e[o++]}}}throw TypeError("Invalid attempt to iterate non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}import{hasValidList as e}from"../hooks/useObserver.js";export var Store=function(e){var t=this,r=e.context,o=e.observer,n=e.id;this.context=null,this.observer=null,this.id=null,this.notify=function(e){return t.observer.notify({context:t.context,value:e})},this.query=function(){return console.log("method is not conencted to the reducer, please call useStore first")},this.mutate=function(){return console.log("method is not connected to the store, you need call useStore first")},this.id=n,this.context=r,this.observer=o};export var MicroStore=function(){var t=this;this.collection=new Map,this.listeners=new Map,this.subscribeStore=function(r,o){for(var n,i,s=o.observer,l=o.context,a=null!=(n=t.listeners.get(r))?n:[],u=_create_for_of_iterator_helper_loose(a);!(i=u()).done;)!function(){var t=i.value,r=function(r,o){var n;e([l],r)&&(null==r||null==(n=r.context)||n.update({value:r,listener:t}),null==t||t(r,o))};r.id=t.id,s.has(t.id)||s.subscribe(r)}()},this.add=function(e,r){return t.subscribeStore(e,r),t.collection.set(e,r),r},this.registerListener=function(e,r){if(t.listeners.has(e)){var o=t.listeners.get(e);o.push(r),t.listeners.set(e,o)}else t.listeners.set(e,[r])},this.hasListener=function(e){for(var r,o=!1,n=_create_for_of_iterator_helper_loose(t.listeners);!(r=n()).done;){var i=r.value;if(o=(i[0],i[1]).some(function(t){return t.id===e}))break}return o},this.remove=function(e,r){for(var o,n,i=t.collection.get(e),s=null!=(o=t.listeners.get(e))?o:[],l=_create_for_of_iterator_helper_loose(s);!(n=l()).done;){var a=n.value;if(a.id===r){i.observer.has(a.id)&&i.observer.unsubscribe(a);var u=s.indexOf(a);u>-1&&s.splice(u,1)}}},this.removeAll=function(e){for(var r,o,n=t.collection.get(e),i=null!=(r=t.listeners.get(e))?r:[],s=_create_for_of_iterator_helper_loose(i);!(o=s()).done;){var l=o.value;n.observer.has(l.id)&&n.observer.unsubscribe(l);var a=i.indexOf(l);a>-1&&i.splice(a,1)}},this.get=function(e){return t.collection.get(e)},this.has=function(e){return t.collection.has(e)}};
1
+ import { hasValidList } from "../hooks/useObserver";
2
+ export class Store {
3
+ constructor({ context, observer, id }) {
4
+ this.notify = (value) => this.observer.notify({ context: this.context, value });
5
+ this.query = () => console.log("method is not connected to the reducer, please call useStore first");
6
+ this.mutate = () => console.log("method is not connected to the store, you need call useStore first");
7
+ this.id = id;
8
+ this.context = context;
9
+ this.observer = observer;
10
+ }
11
+ }
12
+ export class MicroStore {
13
+ constructor() {
14
+ this.collection = new Map();
15
+ this.listeners = new Map();
16
+ this.subscribeStore = (id, store) => {
17
+ const { observer, context } = store;
18
+ const listeners = this.listeners.get(id) ?? [];
19
+ for (const listener of listeners) {
20
+ if (observer.has(listener.id))
21
+ continue;
22
+ const subscriber = function (payload, resolve) {
23
+ const isInvalidContext = !hasValidList([context], payload);
24
+ if (isInvalidContext)
25
+ return;
26
+ payload?.context &&
27
+ payload.context.update?.({
28
+ value: payload,
29
+ listener: listener,
30
+ });
31
+ listener?.(payload, resolve);
32
+ };
33
+ subscriber.id = listener.id;
34
+ if (!observer.has(listener.id))
35
+ observer.subscribe(subscriber);
36
+ }
37
+ };
38
+ this.add = (id, store, _name) => {
39
+ this.subscribeStore(id, store);
40
+ this.collection.set(id, store);
41
+ return store;
42
+ };
43
+ this.registerListener = (id, cb) => {
44
+ if (this.listeners.has(id)) {
45
+ const listeners = this.listeners.get(id);
46
+ listeners.push(cb);
47
+ this.listeners.set(id, listeners);
48
+ }
49
+ else {
50
+ this.listeners.set(id, [cb]);
51
+ }
52
+ };
53
+ this.hasListener = (id) => {
54
+ let result = false;
55
+ for (const [, listener] of this.listeners) {
56
+ result = listener.some((cb) => cb.id === id);
57
+ if (result)
58
+ break;
59
+ }
60
+ return result;
61
+ };
62
+ this.remove = (id, mutationId) => {
63
+ const store = this.collection.get(id);
64
+ if (!store)
65
+ return;
66
+ const listeners = this.listeners.get(id) ?? [];
67
+ for (const listener of listeners) {
68
+ if (listener.id !== mutationId)
69
+ continue;
70
+ if (store.observer.has(listener.id)) {
71
+ store.observer.unsubscribe(listener);
72
+ }
73
+ const index = listeners.indexOf(listener);
74
+ if (index > -1)
75
+ listeners.splice(index, 1);
76
+ }
77
+ };
78
+ this.removeAll = (id) => {
79
+ const store = this.collection.get(id);
80
+ if (!store)
81
+ return;
82
+ const listeners = this.listeners.get(id) ?? [];
83
+ for (const listener of listeners) {
84
+ if (store.observer.has(listener.id)) {
85
+ store.observer.unsubscribe(listener);
86
+ }
87
+ const index = listeners.indexOf(listener);
88
+ if (index > -1)
89
+ listeners.splice(index, 1);
90
+ }
91
+ };
92
+ this.get = (id) => this.collection.get(id);
93
+ this.has = (id) => this.collection.has(id);
94
+ }
95
+ }
package/lib/utils.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export declare const getStackTrace: () => string | undefined;
2
+ export declare const randomId: () => string;
package/lib/utils.js CHANGED
@@ -1 +1,5 @@
1
- export var getStackTrace=function(){return Error().stack};export var randomId=function(){return Math.random().toString(36).substring(2,16)};
1
+ export const getStackTrace = () => {
2
+ const error = new Error();
3
+ return error.stack;
4
+ };
5
+ export const randomId = () => Math.random().toString(36).substring(2, 16);
package/package.json CHANGED
@@ -1,16 +1,19 @@
1
1
  {
2
2
  "name": "hermes-io",
3
- "version": "2.11.95",
3
+ "version": "2.12.97",
4
4
  "type": "module",
5
5
  "description": "A lightweight React library that allows communication between Reactjs components by using the observer pattern and the hook api",
6
6
  "main": "./lib/index.js",
7
7
  "module": "./lib/index.js",
8
+ "types": "./lib/index.d.ts",
8
9
  "scripts": {
9
10
  "test": "vitest __test__",
10
- "prepare": "swc ./src -d ./lib"
11
+ "build": "tsc",
12
+ "prepare": "tsc"
11
13
  },
12
14
  "exports": {
13
15
  ".": {
16
+ "types": "./lib/index.d.ts",
14
17
  "import": "./lib/index.js",
15
18
  "require": "./lib/index.js"
16
19
  }
@@ -27,21 +30,19 @@
27
30
  "react": "^18.2.0"
28
31
  },
29
32
  "devDependencies": {
30
- "@sveltejs/vite-plugin-svelte": "^3.0.2",
31
- "@swc/cli": "^0.1.62",
32
- "@swc/core": "^1.3.71",
33
33
  "@testing-library/dom": "^9.3.4",
34
34
  "@testing-library/jest-dom": "^6.4.2",
35
35
  "@testing-library/react": "^14.2.1",
36
36
  "@testing-library/react-hooks": "^8.0.1",
37
- "@testing-library/svelte": "^4.1.0",
38
37
  "@testing-library/user-event": "^14.5.2",
39
- "@vitejs/plugin-react": "^4.2.1",
38
+ "@types/react": "^19.2.14",
39
+ "@types/react-dom": "^19.2.3",
40
+ "@vitejs/plugin-react-swc": "^3.6.0",
40
41
  "happy-dom": "^13.3.8",
41
42
  "react": "^18.2.0",
42
43
  "react-dom": "^18.2.0",
44
+ "typescript": "^6.0.2",
43
45
  "vite": "^5.1.0",
44
- "vitest": "^1.2.2",
45
- "@vitejs/plugin-react-swc": "^3.6.0"
46
+ "vitest": "^1.2.2"
46
47
  }
47
48
  }
package/tsconfig.json ADDED
@@ -0,0 +1,17 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "module": "ESNext",
5
+ "moduleResolution": "bundler",
6
+ "jsx": "react-jsx",
7
+ "strict": true,
8
+ "esModuleInterop": true,
9
+ "skipLibCheck": true,
10
+ "declaration": true,
11
+ "declarationDir": "./lib",
12
+ "outDir": "./lib",
13
+ "rootDir": "./src"
14
+ },
15
+ "include": ["src"],
16
+ "exclude": ["node_modules", "lib", "__test__", "src/setupTests.ts"]
17
+ }
@@ -1,6 +0,0 @@
1
- import React from 'react';
2
-
3
- export function withNotify(Component, { context, observer }) {
4
- const notify = (value) => observer.notify({ context, value });
5
- return (props) => <Component notify={notify} {...props} />;
6
- }
@@ -1 +0,0 @@
1
- import{useEffect as l}from"react";export var useMicroStore=function(r){var n=r.name,o=r.id,a=r.microStore,u=r.store;l(function(){var l,r;if(!(!o||(null==a?void 0:null==(l=a.has)?void 0:l.call(a,o))))return null==a||null==(r=a.add)||r.call(a,o,u,n),function(){var l;null==a||null==(l=a.removeAll)||l.call(a,o)}},[a,u,o])};
@@ -1 +0,0 @@
1
- import{useStore as r}from"./useStore.js";import{Context as e}from"../context/context.js";import{Observer as o}from"../observer/observer.js";import{Store as t}from"../store/store.js";import{useMicroStore as s}from"./useMicroStore.js";export var useObservableStore=function(m,i,n,c,a){var f=r({microStore:c,store:new t({id:m,context:new e("Context_"+m),observer:new o}),reducer:n,data:i}).store;return s({id:m,microStore:c,store:f,name:a}),{store:f}};
@@ -1 +0,0 @@
1
- import{useStore as r}from"./useStore";import{Context as e}from"../context/context";import{Observer as o}from"../observer/observer";import{Store as t}from"../store/store";export var useStoreFactory=function(n,s,m,c){var i={store:new t({id:n,context:new e("Context_"+n),observer:new o}),reducer:m,data:s};return c&&(i.microStore=c),{store:r(i).store}};