@tamagui/use-store 1.50.0 → 1.50.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.
package/src/selector.tsx CHANGED
@@ -2,7 +2,8 @@ import { useEffect, useState } from 'react'
2
2
 
3
3
  import { isEqualSubsetShallow } from './comparators'
4
4
  import { UNWRAP_PROXY } from './constants'
5
- import { setIsInReaction, trackStoresAccess } from './useStore'
5
+ import { StoreInfo } from './interfaces'
6
+ import { trackStoresAccess } from './useStore'
6
7
 
7
8
  // TODO i think we can just replace reaction() with this, its not worse in any way
8
9
 
@@ -25,46 +26,46 @@ const logUpdate =
25
26
  }
26
27
  : null
27
28
 
28
- // TODO test this works the same as useSelector
29
- export function selector(fn: () => any) {
30
- let prev = runStoreSelector(fn)
31
- let disposeValue: Function | null = null
32
- const subscribe = () => {
33
- return subscribeToStores([...prev.stores], () => {
34
- try {
35
- disposeValue?.()
36
- setIsInReaction(true)
37
- const next = runStoreSelector(fn)
38
- if (typeof next.value === 'function') {
39
- disposeValue = next.value
40
- if (process.env.NODE_ENV === 'development') {
41
- logUpdate!(fn, [...next.stores], '(fn)', '(fn)')
42
- }
43
- return
44
- }
45
- if (
46
- isEqualSubsetShallow(prev.stores, next.stores) &&
47
- isEqualSubsetShallow(prev.value, next.value)
48
- ) {
49
- return
50
- }
51
- if (process.env.NODE_ENV === 'development') {
52
- logUpdate!(fn, [...next.stores], prev.value, next.value)
53
- }
54
- prev = next
55
- dispose()
56
- dispose = subscribe()
57
- } finally {
58
- setIsInReaction(false)
59
- }
60
- })
61
- }
62
- let dispose = subscribe()
63
- return () => {
64
- dispose()
65
- disposeValue?.()
66
- }
67
- }
29
+ // // TODO test this works the same as useSelector
30
+ // export function selector(fn: () => any) {
31
+ // let prev = runStoreSelector(fn)
32
+ // let disposeValue: Function | null = null
33
+ // const subscribe = () => {
34
+ // return subscribeToStores([...prev.storeInfos], () => {
35
+ // try {
36
+ // disposeValue?.()
37
+ // setIsInReaction(true)
38
+ // const next = runStoreSelector(fn)
39
+ // if (typeof next.value === 'function') {
40
+ // disposeValue = next.value
41
+ // if (process.env.NODE_ENV === 'development') {
42
+ // logUpdate!(fn, [...next.storeInfos], '(fn)', '(fn)')
43
+ // }
44
+ // return
45
+ // }
46
+ // if (
47
+ // isEqualSubsetShallow(prev.stores, next.stores) &&
48
+ // isEqualSubsetShallow(prev.value, next.value)
49
+ // ) {
50
+ // return
51
+ // }
52
+ // if (process.env.NODE_ENV === 'development') {
53
+ // logUpdate!(fn, [...next.stores], prev.value, next.value)
54
+ // }
55
+ // prev = next
56
+ // dispose()
57
+ // dispose = subscribe()
58
+ // } finally {
59
+ // setIsInReaction(false)
60
+ // }
61
+ // })
62
+ // }
63
+ // let dispose = subscribe()
64
+ // return () => {
65
+ // dispose()
66
+ // disposeValue?.()
67
+ // }
68
+ // }
68
69
 
69
70
  export function useSelector<A>(fn: () => A): A {
70
71
  const [state, setState] = useState(() => {
@@ -73,26 +74,30 @@ export function useSelector<A>(fn: () => A): A {
73
74
 
74
75
  useEffect(() => {
75
76
  let dispose
76
- const unsub = subscribeToStores([...state.stores], () => {
77
+ const unsub = subscribeToStores([...state.storeInfos], () => {
77
78
  dispose?.()
78
79
  const next = runStoreSelector(fn)
80
+
81
+ const nextStoreInfos = [...next.storeInfos]
82
+ const prevStoreInfos = [...state.storeInfos]
83
+
79
84
  // return function === return disposable
80
85
  if (typeof next.value === 'function') {
81
86
  if (process.env.NODE_ENV === 'development') {
82
- logUpdate!(fn, [...next.stores], '(fn)', '(fn)')
87
+ logUpdate!(fn, nextStoreInfos, '(fn)', '(fn)')
83
88
  }
84
89
  dispose = next.value
85
90
  return
86
91
  }
87
92
  setState((prev) => {
88
93
  if (
89
- isEqualSubsetShallow(prev.stores, next.stores) &&
94
+ isEqualSubsetShallow(prevStoreInfos, nextStoreInfos) &&
90
95
  isEqualSubsetShallow(prev.value, next.value)
91
96
  ) {
92
97
  return prev
93
98
  }
94
99
  if (process.env.NODE_ENV === 'development') {
95
- logUpdate!(fn, [...next.stores], prev.value, next.value)
100
+ logUpdate!(fn, nextStoreInfos, prev.value, next.value)
96
101
  }
97
102
  return next
98
103
  })
@@ -101,25 +106,28 @@ export function useSelector<A>(fn: () => A): A {
101
106
  unsub()
102
107
  dispose?.()
103
108
  }
104
- }, [...state.stores])
109
+ }, [[...state.storeInfos].map((i) => i.uid).join(',')])
105
110
 
106
111
  return state.value
107
112
  }
108
113
 
109
- function runStoreSelector<A>(selector: () => A): { value: A; stores: Set<any> } {
110
- const stores = new Set()
111
- const dispose = trackStoresAccess((store) => {
112
- stores.add(store)
114
+ function runStoreSelector<A>(selector: () => A): {
115
+ value: A
116
+ storeInfos: Set<StoreInfo>
117
+ } {
118
+ const storeInfos = new Set<StoreInfo>()
119
+ const dispose = trackStoresAccess((storeInfo) => {
120
+ storeInfos.add(storeInfo)
113
121
  })
114
122
  const value = selector()
115
123
  dispose()
116
124
  return {
117
125
  value,
118
- stores,
126
+ storeInfos,
119
127
  }
120
128
  }
121
129
 
122
- function subscribeToStores(stores: any[], onUpdate: () => any) {
130
+ function subscribeToStores(stores: StoreInfo[], onUpdate: () => any) {
123
131
  const disposes: Function[] = []
124
132
  for (const store of stores) {
125
133
  disposes.push(store.subscribe(onUpdate))
package/src/useStore.tsx CHANGED
@@ -1,4 +1,4 @@
1
- import { useCallback, useEffect, useRef, useState, useSyncExternalStore } from 'react'
1
+ import { useCallback, useRef, useSyncExternalStore } from 'react'
2
2
 
3
3
  import { isEqualSubsetShallow } from './comparators'
4
4
  import { configureOpts } from './configureUseStore'
@@ -10,21 +10,13 @@ import {
10
10
  getStoreUid,
11
11
  simpleStr,
12
12
  } from './helpers'
13
- import { Selector, StoreInfo, UseStoreOptions } from './interfaces'
14
- import {
15
- SHOULD_DEBUG,
16
- Store,
17
- StoreTracker,
18
- TRIGGER_UPDATE,
19
- disableTracking,
20
- setDisableStoreTracking,
21
- } from './Store'
22
- import { DebugStores, useCurrentComponent } from './useStoreDebug'
13
+ import { Selector, Store, StoreInfo, UseStoreOptions } from './interfaces'
14
+ import { DebugStores, shouldDebug, useCurrentComponent } from './useStoreDebug'
23
15
 
24
16
  const idFn = (_) => _
25
17
 
26
18
  // no singleton, just react
27
- export function useStore<A extends Store<B>, B extends Object>(
19
+ export function useStore<A, B extends Object>(
28
20
  StoreKlass: (new (props: B) => A) | (new () => A),
29
21
  props?: B | null,
30
22
  options: UseStoreOptions<A, any> = defaultOptions
@@ -35,7 +27,7 @@ export function useStore<A extends Store<B>, B extends Object>(
35
27
  return useStoreFromInfo(info, selector, options)
36
28
  }
37
29
 
38
- export function useStoreDebug<A extends Store<B>, B extends Object>(
30
+ export function useStoreDebug<A, B extends Object>(
39
31
  StoreKlass: (new (props: B) => A) | (new () => A),
40
32
  props?: B
41
33
  ): A {
@@ -43,7 +35,7 @@ export function useStoreDebug<A extends Store<B>, B extends Object>(
43
35
  }
44
36
 
45
37
  // singleton
46
- export function createStore<A extends Store<B>, B extends Object>(
38
+ export function createStore<A, B extends Object>(
47
39
  StoreKlass: new (props: B) => A | (new () => A),
48
40
  props?: B,
49
41
  options?: UseStoreOptions<A, any>
@@ -56,10 +48,7 @@ export function createStore<A extends Store<B>, B extends Object>(
56
48
  // use singleton with react
57
49
  // TODO selector support with types...
58
50
 
59
- export function useGlobalStore<A extends Store<B>, B extends Object>(
60
- instance: A,
61
- debug?: boolean
62
- ): A {
51
+ export function useGlobalStore<A, B extends Object>(instance: A, debug?: boolean): A {
63
52
  const store = instance[UNWRAP_PROXY]
64
53
  const uid = getStoreUid(store.constructor, store.props)
65
54
  const info = cache.get(uid)
@@ -69,11 +58,7 @@ export function useGlobalStore<A extends Store<B>, B extends Object>(
69
58
  return useStoreFromInfo(info, undefined, { debug })
70
59
  }
71
60
 
72
- export function useGlobalStoreSelector<
73
- A extends Store<B>,
74
- B extends Object,
75
- Selector extends (store: A) => any
76
- >(
61
+ export function useGlobalStoreSelector<A, Selector extends (store: A) => any>(
77
62
  instance: A,
78
63
  selector: Selector,
79
64
  debug?: boolean
@@ -127,7 +112,7 @@ export function useStoreSelector<
127
112
  return useStore(StoreKlass, props, { selector }) as any
128
113
  }
129
114
 
130
- type StoreAccessTracker = (store: any) => void
115
+ type StoreAccessTracker = (store: StoreInfo) => void
131
116
  const storeAccessTrackers = new Set<StoreAccessTracker>()
132
117
  export function trackStoresAccess(cb: StoreAccessTracker) {
133
118
  storeAccessTrackers.add(cb)
@@ -136,27 +121,38 @@ export function trackStoresAccess(cb: StoreAccessTracker) {
136
121
  }
137
122
  }
138
123
 
139
- // get non-singleton outside react (weird)
140
- export function getStore<A extends Store<B>, B extends Object>(
124
+ export function getStore<A, B extends Object>(
141
125
  StoreKlass: (new (props: B) => A) | (new () => A),
142
126
  props?: B
143
127
  ): A {
144
- return getOrCreateStoreInfo(StoreKlass, props).store as any
128
+ return getStoreInfo(StoreKlass, props).store as any
129
+ }
130
+
131
+ // just like getOrCreateStoreInfo but refuses to create
132
+ export function getStoreInfo(StoreKlass: any, props: any) {
133
+ return getOrCreateStoreInfo(StoreKlass, props, {
134
+ refuseCreation: true,
135
+ })
145
136
  }
146
137
 
147
138
  function getOrCreateStoreInfo(
148
139
  StoreKlass: any,
149
140
  props: any,
150
- options?: UseStoreOptions & { avoidCache?: boolean },
141
+ options?: UseStoreOptions & { avoidCache?: boolean; refuseCreation?: boolean },
151
142
  propsKeyCalculated?: string
152
143
  ) {
153
144
  const uid = getStoreUid(StoreKlass, propsKeyCalculated ?? props)
154
145
  if (!options?.avoidCache && cache.has(uid)) {
155
146
  return cache.get(uid)!
156
147
  }
148
+ if (options?.refuseCreation) {
149
+ throw new Error(`No store exists (${StoreKlass.name}) with props: ${props}`)
150
+ }
157
151
 
158
152
  // init
159
153
  const storeInstance = new StoreKlass(props!)
154
+ // add props
155
+ storeInstance.props = props
160
156
 
161
157
  const getters = {}
162
158
  const actions = {}
@@ -177,22 +173,44 @@ function getOrCreateStoreInfo(
177
173
  }
178
174
 
179
175
  const keyComparators = storeInstance['_comparators']
176
+ const listeners = new Set<Function>()
177
+
180
178
  const storeInfo = {
179
+ uid: Math.random(),
181
180
  keyComparators,
182
181
  storeInstance,
183
182
  getters,
184
183
  stateKeys,
185
184
  actions,
186
185
  debug: options?.debug,
186
+ disableTracking: false,
187
187
  gettersState: {
188
188
  getCache: new Map<string, any>(),
189
189
  depsToGetter: new Map<string, Set<string>>(),
190
190
  curGetKeys: new Set<string>(),
191
191
  isGetting: false,
192
192
  },
193
- }
193
+ listeners,
194
+ trackers: new Set(),
195
+ version: 0,
196
+ subscribe: (onChanged: Function) => {
197
+ listeners.add(onChanged)
198
+ return () => {
199
+ listeners.delete(onChanged)
200
+ }
201
+ },
202
+ triggerUpdate: () => {
203
+ storeInfo.version = (storeInfo.version + 1) % Number.MAX_SAFE_INTEGER
204
+ for (const cb of listeners) {
205
+ cb()
206
+ }
207
+ },
208
+ } satisfies Omit<StoreInfo, 'store'>
194
209
 
195
- const store = createProxiedStore(storeInfo)
210
+ const store = createProxiedStore(
211
+ // we assign store right after and proxiedStore never accesses it until later on
212
+ storeInfo as any as StoreInfo
213
+ )
196
214
 
197
215
  // uses more memory when on
198
216
  if (process.env.NODE_ENV === 'development') {
@@ -202,15 +220,15 @@ function getOrCreateStoreInfo(
202
220
  // if has a mount function call it
203
221
  store.mount?.()
204
222
 
205
- const value: StoreInfo = {
206
- ...storeInfo,
207
- store,
208
- }
223
+ // @ts-ignore
224
+ storeInfo.store = store
225
+
226
+ const result = storeInfo as any as StoreInfo
209
227
 
210
228
  // still set even when avoidCache is true (hmr)
211
- cache.set(uid, value)
229
+ cache.set(uid, result)
212
230
 
213
- return value
231
+ return result
214
232
  }
215
233
 
216
234
  export const allStores = {}
@@ -257,7 +275,7 @@ function useStoreFromInfo(
257
275
  const getSnapshot = useCallback(() => {
258
276
  const curInternal = internal.current!
259
277
  const keys = [...(!curInternal.tracked.size ? info.stateKeys : curInternal.tracked)]
260
- const nextKeys = `${store._version}${keys.join('')}${userSelector || ''}`
278
+ const nextKeys = `${info.version}${keys.join('')}${userSelector || ''}`
261
279
  const lastKeys = curInternal.lastKeys
262
280
 
263
281
  // avoid updates
@@ -269,14 +287,14 @@ function useStoreFromInfo(
269
287
 
270
288
  let snap: any
271
289
  // dont track during selector
272
- setDisableStoreTracking(store, true)
290
+ info.disableTracking = true
273
291
  const last = curInternal.last
274
292
  if (userSelector) {
275
293
  snap = userSelector(store)
276
294
  } else {
277
295
  snap = selectKeys(store, keys)
278
296
  }
279
- setDisableStoreTracking(store, false)
297
+ info.disableTracking = false
280
298
 
281
299
  // this wasn't updating in AnimationsStore
282
300
  const isUnchanged =
@@ -300,7 +318,7 @@ function useStoreFromInfo(
300
318
  }, [])
301
319
 
302
320
  // sync by default
303
- const state = useSyncExternalStore(store.subscribe, getSnapshot, getSnapshot)
321
+ const state = useSyncExternalStore(info.subscribe, getSnapshot, getSnapshot)
304
322
 
305
323
  if (userSelector) {
306
324
  return state
@@ -315,6 +333,7 @@ function useStoreFromInfo(
315
333
  return curVal
316
334
  }
317
335
  const keyString = key as string // fine for our uses
336
+
318
337
  if (info.stateKeys.has(keyString) || keyString in info.getters) {
319
338
  if (shouldPrintDebug) {
320
339
  // rome-ignore lint/nursery/noConsoleLog: <explanation>
@@ -333,14 +352,13 @@ function useStoreFromInfo(
333
352
  let setters = new Set<any>()
334
353
  const logStack = new Set<Set<any[]> | 'end'>()
335
354
 
336
- function createProxiedStore(storeInfo: Omit<StoreInfo, 'store' | 'source'>) {
355
+ function createProxiedStore(storeInfo: StoreInfo) {
337
356
  const { actions, storeInstance, getters, gettersState } = storeInfo
338
357
  const { getCache, curGetKeys, depsToGetter } = gettersState
339
358
  const constr = storeInstance.constructor
340
359
  const shouldDebug = storeInfo.debug ?? DebugStores.has(constr)
341
360
 
342
361
  let didSet = false
343
- let isInAction = false
344
362
  const wrappedActions = {}
345
363
 
346
364
  // pre-setup actions
@@ -364,10 +382,8 @@ function createProxiedStore(storeInfo: Omit<StoreInfo, 'store' | 'source'>) {
364
382
  }
365
383
  if (process.env.NODE_ENV === 'development' && shouldDebug) {
366
384
  // rome-ignore lint/nursery/noConsoleLog: <explanation>
367
- console.log('(debug) startAction', key, { isInAction })
385
+ console.log('(debug) startAction', key)
368
386
  }
369
- // dumb for now
370
- isInAction = true
371
387
  res = Reflect.apply(actionFn, proxiedStore, args)
372
388
  if (res instanceof Promise) {
373
389
  return res.then(finishAction)
@@ -502,9 +518,8 @@ function createProxiedStore(storeInfo: Omit<StoreInfo, 'store' | 'source'>) {
502
518
  // rome-ignore lint/nursery/noConsoleLog: <explanation>
503
519
  console.log('(debug) finishAction', { didSet })
504
520
  }
505
- isInAction = false
506
521
  if (didSet) {
507
- storeInstance[TRIGGER_UPDATE]?.()
522
+ storeInfo.triggerUpdate()
508
523
  didSet = false
509
524
  }
510
525
  return val
@@ -528,11 +543,11 @@ function createProxiedStore(storeInfo: Omit<StoreInfo, 'store' | 'source'>) {
528
543
  if (key === UNWRAP_STORE_INFO) {
529
544
  return storeInfo
530
545
  }
531
- const trackingDisabled = disableTracking.get(storeInstance)
546
+ const trackingDisabled = storeInfo.disableTracking
532
547
  if (!trackingDisabled) {
533
548
  if (storeAccessTrackers.size && !storeAccessTrackers.has(storeInstance)) {
534
549
  for (const t of storeAccessTrackers) {
535
- t(storeInstance)
550
+ t(storeInfo)
536
551
  }
537
552
  }
538
553
  }
@@ -585,6 +600,7 @@ function createProxiedStore(storeInfo: Omit<StoreInfo, 'store' | 'source'>) {
585
600
  set(target, key, value, receiver) {
586
601
  const cur = Reflect.get(target, key)
587
602
  const res = Reflect.set(target, key, value, receiver)
603
+
588
604
  // only update if changed, simple compare
589
605
  if (res && cur !== value) {
590
606
  // clear getters cache that rely on this
@@ -593,21 +609,21 @@ function createProxiedStore(storeInfo: Omit<StoreInfo, 'store' | 'source'>) {
593
609
  }
594
610
  if (shouldDebug) {
595
611
  setters.add({ key, value })
596
- if (storeInstance[SHOULD_DEBUG]()) {
612
+ if (getShouldDebug(storeInfo)) {
597
613
  // rome-ignore lint/nursery/noConsoleLog: <explanation>
598
614
  console.log('(debug) SET', res, key, value)
599
615
  }
600
616
  }
601
617
  if (process.env.NODE_ENV === 'development' && shouldDebug) {
602
618
  // rome-ignore lint/nursery/noConsoleLog: <explanation>
603
- console.log('SET...', { key, value, isInAction })
619
+ console.log('SET...', { key, value })
604
620
  }
605
- if (isInAction) {
606
- didSet = true
607
- } else {
621
+
622
+ if (!isTriggering) {
623
+ // trigger only once per event loop
608
624
  isTriggering = true
609
- queueMicrotask(() => {
610
- storeInstance[TRIGGER_UPDATE]?.()
625
+ waitForEventLoop(() => {
626
+ storeInfo.triggerUpdate()
611
627
  isTriggering = false
612
628
  })
613
629
  }
@@ -617,12 +633,12 @@ function createProxiedStore(storeInfo: Omit<StoreInfo, 'store' | 'source'>) {
617
633
  })
618
634
 
619
635
  function clearGetterCache(setKey: string) {
620
- const getters = depsToGetter.get(setKey)
636
+ const parentGetters = depsToGetter.get(setKey)
621
637
  getCache.delete(setKey)
622
- if (!getters) {
638
+ if (!parentGetters) {
623
639
  return
624
640
  }
625
- for (const gk of getters) {
641
+ for (const gk of parentGetters) {
626
642
  getCache.delete(gk)
627
643
  if (depsToGetter.has(gk)) {
628
644
  clearGetterCache(gk)
@@ -633,6 +649,9 @@ function createProxiedStore(storeInfo: Omit<StoreInfo, 'store' | 'source'>) {
633
649
  return proxiedStore
634
650
  }
635
651
 
652
+ const waitForEventLoop =
653
+ process.env.NODE_ENV === 'test' ? (cb: Function) => cb() : queueMicrotask
654
+
636
655
  let counter = 0
637
656
 
638
657
  const passThroughKeys = {
@@ -643,3 +662,18 @@ const passThroughKeys = {
643
662
  _listeners: true,
644
663
  _enableTracking: true,
645
664
  }
665
+
666
+ export type StoreTracker = {
667
+ tracked: Set<string>
668
+ component?: any
669
+ last?: any
670
+ lastKeys?: any
671
+ }
672
+
673
+ function getShouldDebug(storeInfo: StoreInfo) {
674
+ const info = { storeInstance: storeInfo.store }
675
+ const trackers = storeInfo.trackers
676
+ return [...trackers].some(
677
+ (tracker) => tracker.component && shouldDebug(tracker.component, info)
678
+ )
679
+ }
package/types/index.d.ts CHANGED
@@ -3,8 +3,11 @@ export { configureUseStore } from './configureUseStore';
3
3
  export * from './interfaces';
4
4
  export * from './selector';
5
5
  export * from './reaction';
6
- export * from './Store';
7
6
  export { UNWRAP_PROXY } from './constants';
8
7
  export * from './comparators';
9
8
  export * from './decorators';
9
+ export declare class Store<Props extends Record<string, any>> {
10
+ props: Props;
11
+ constructor(props: Props);
12
+ }
10
13
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA;AAC1B,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AACvD,cAAc,cAAc,CAAA;AAC5B,cAAc,YAAY,CAAA;AAC1B,cAAc,YAAY,CAAA;AAC1B,cAAc,SAAS,CAAA;AACvB,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC1C,cAAc,eAAe,CAAA;AAC7B,cAAc,cAAc,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA;AAC1B,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AACvD,cAAc,cAAc,CAAA;AAC5B,cAAc,YAAY,CAAA;AAC1B,cAAc,YAAY,CAAA;AAC1B,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC1C,cAAc,eAAe,CAAA;AAC7B,cAAc,cAAc,CAAA;AAG5B,qBAAa,KAAK,CAAC,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAC/B,KAAK,EAAE,KAAK;gBAAZ,KAAK,EAAE,KAAK;CAChC"}
@@ -1,4 +1,4 @@
1
- import { Store } from './Store';
1
+ import { StoreTracker } from './useStore';
2
2
  export type Selector<A = unknown, B = unknown> = (x: A) => B;
3
3
  export type UseStoreSelector<Store, Res> = (store: Store) => Res;
4
4
  export type UseStoreOptions<Store = any, SelectorRes = any> = {
@@ -6,7 +6,12 @@ export type UseStoreOptions<Store = any, SelectorRes = any> = {
6
6
  selector?: UseStoreSelector<Store, SelectorRes>;
7
7
  once?: boolean;
8
8
  };
9
+ export interface Store<Props = Record<string, any> | null | undefined> {
10
+ new (...args: any[]): any;
11
+ props: Props;
12
+ }
9
13
  export type StoreInfo<A = Store> = {
14
+ uid: number;
10
15
  keyComparators?: {
11
16
  [key: string]: (a: any, b: any) => boolean;
12
17
  };
@@ -24,6 +29,12 @@ export type StoreInfo<A = Store> = {
24
29
  curGetKeys: Set<string>;
25
30
  isGetting: boolean;
26
31
  };
32
+ listeners: Set<Function>;
33
+ trackers: Set<StoreTracker>;
34
+ version: number;
35
+ subscribe: (onChanged: () => void) => () => void;
36
+ triggerUpdate: Function;
37
+ disableTracking: boolean;
27
38
  };
28
39
  export type UseStoreConfig = {
29
40
  logLevel?: 'debug' | 'info' | 'error';
@@ -1 +1 @@
1
- {"version":3,"file":"interfaces.d.ts","sourceRoot":"","sources":["../src/interfaces.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAE/B,MAAM,MAAM,QAAQ,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAA;AAE5D,MAAM,MAAM,gBAAgB,CAAC,KAAK,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,KAAK,KAAK,GAAG,CAAA;AAChE,MAAM,MAAM,eAAe,CAAC,KAAK,GAAG,GAAG,EAAE,WAAW,GAAG,GAAG,IAAI;IAC5D,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,QAAQ,CAAC,EAAE,gBAAgB,CAAC,KAAK,EAAE,WAAW,CAAC,CAAA;IAC/C,IAAI,CAAC,EAAE,OAAO,CAAA;CACf,CAAA;AAED,MAAM,MAAM,SAAS,CAAC,CAAC,GAAG,KAAK,IAAI;IACjC,cAAc,CAAC,EAAE;QACf,CAAC,GAAG,EAAE,MAAM,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,KAAK,OAAO,CAAA;KAC3C,CAAA;IAED,KAAK,EAAE,CAAC,CAAA;IACR,aAAa,EAAE,GAAG,CAAA;IAClB,OAAO,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAE,CAAA;IAC/B,OAAO,EAAE,GAAG,CAAA;IACZ,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IACtB,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,YAAY,EAAE;QACZ,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;QAC1B,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAA;QACtC,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;QACvB,SAAS,EAAE,OAAO,CAAA;KACnB,CAAA;CACF,CAAA;AAED,MAAM,MAAM,cAAc,GAAG;IAC3B,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,OAAO,CAAA;CACtC,CAAA"}
1
+ {"version":3,"file":"interfaces.d.ts","sourceRoot":"","sources":["../src/interfaces.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAEzC,MAAM,MAAM,QAAQ,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAA;AAE5D,MAAM,MAAM,gBAAgB,CAAC,KAAK,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,KAAK,KAAK,GAAG,CAAA;AAChE,MAAM,MAAM,eAAe,CAAC,KAAK,GAAG,GAAG,EAAE,WAAW,GAAG,GAAG,IAAI;IAC5D,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,QAAQ,CAAC,EAAE,gBAAgB,CAAC,KAAK,EAAE,WAAW,CAAC,CAAA;IAC/C,IAAI,CAAC,EAAE,OAAO,CAAA;CACf,CAAA;AAED,MAAM,WAAW,KAAK,CAAC,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,GAAG,SAAS;IACnE,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,GAAG,CAAA;IACzB,KAAK,EAAE,KAAK,CAAA;CACb;AAED,MAAM,MAAM,SAAS,CAAC,CAAC,GAAG,KAAK,IAAI;IACjC,GAAG,EAAE,MAAM,CAAA;IACX,cAAc,CAAC,EAAE;QACf,CAAC,GAAG,EAAE,MAAM,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,KAAK,OAAO,CAAA;KAC3C,CAAA;IAED,KAAK,EAAE,CAAC,CAAA;IACR,aAAa,EAAE,GAAG,CAAA;IAClB,OAAO,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAE,CAAA;IAC/B,OAAO,EAAE,GAAG,CAAA;IACZ,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IACtB,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,YAAY,EAAE;QACZ,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;QAC1B,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAA;QACtC,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;QACvB,SAAS,EAAE,OAAO,CAAA;KACnB,CAAA;IACD,SAAS,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAA;IACxB,QAAQ,EAAE,GAAG,CAAC,YAAY,CAAC,CAAA;IAC3B,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,CAAC,SAAS,EAAE,MAAM,IAAI,KAAK,MAAM,IAAI,CAAA;IAChD,aAAa,EAAE,QAAQ,CAAA;IACvB,eAAe,EAAE,OAAO,CAAA;CACzB,CAAA;AAED,MAAM,MAAM,cAAc,GAAG;IAC3B,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,OAAO,CAAA;CACtC,CAAA"}
@@ -1,4 +1,4 @@
1
- import { Store } from './Store';
2
- export declare function useReaction<StoreInstance extends Store<any>, Selector extends (a: StoreInstance) => any>(store: StoreInstance, selector: Selector, receiver: Selector extends (a: StoreInstance) => infer Derived ? (a: Derived) => any : unknown, equalityFn?: (a: any, b: any) => boolean, memoArgs?: any[]): () => void;
3
- export declare function reaction<StoreInstance extends Store<any>, Selector extends (a: StoreInstance) => any>(store: StoreInstance, selector: Selector, receiver: Selector extends (a: StoreInstance) => infer Derived ? (a: Derived) => any : unknown, equalityFn?: (a: any, b: any) => boolean): () => void;
1
+ import { StoreInfo } from './interfaces';
2
+ export declare function useReaction<StoreInstance, Selector extends (a: StoreInstance) => any>(store: StoreInstance, selector: Selector, receiver: Selector extends (a: StoreInstance) => infer Derived ? (a: Derived) => any : unknown, props?: Record<string, any>, equalityFn?: (a: any, b: any) => boolean, memoArgs?: any[]): () => void;
3
+ export declare function reaction<StoreInstance extends StoreInfo, Selector extends (a: StoreInstance) => any>({ store, subscribe }: StoreInstance, selector: Selector, receiver: Selector extends (a: StoreInstance) => infer Derived ? (a: Derived) => any : unknown, equalityFn?: (a: any, b: any) => boolean): () => void;
4
4
  //# sourceMappingURL=reaction.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"reaction.d.ts","sourceRoot":"","sources":["../src/reaction.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAS/B,wBAAgB,WAAW,CACzB,aAAa,SAAS,KAAK,CAAC,GAAG,CAAC,EAChC,QAAQ,SAAS,CAAC,CAAC,EAAE,aAAa,KAAK,GAAG,EAE1C,KAAK,EAAE,aAAa,EACpB,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,QAAQ,SAAS,CAAC,CAAC,EAAE,aAAa,KAAK,MAAM,OAAO,GAC1D,CAAC,CAAC,EAAE,OAAO,KAAK,GAAG,GACnB,OAAO,EACX,UAAU,GAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,KAAK,OAA8B,EAC9D,QAAQ,CAAC,EAAE,GAAG,EAAE,cAGjB;AAED,wBAAgB,QAAQ,CACtB,aAAa,SAAS,KAAK,CAAC,GAAG,CAAC,EAChC,QAAQ,SAAS,CAAC,CAAC,EAAE,aAAa,KAAK,GAAG,EAE1C,KAAK,EAAE,aAAa,EACpB,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,QAAQ,SAAS,CAAC,CAAC,EAAE,aAAa,KAAK,MAAM,OAAO,GAC1D,CAAC,CAAC,EAAE,OAAO,KAAK,GAAG,GACnB,OAAO,EACX,UAAU,GAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,KAAK,OAA8B,cAyC/D"}
1
+ {"version":3,"file":"reaction.d.ts","sourceRoot":"","sources":["../src/reaction.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AASxC,wBAAgB,WAAW,CAAC,aAAa,EAAE,QAAQ,SAAS,CAAC,CAAC,EAAE,aAAa,KAAK,GAAG,EACnF,KAAK,EAAE,aAAa,EACpB,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,QAAQ,SAAS,CAAC,CAAC,EAAE,aAAa,KAAK,MAAM,OAAO,GAC1D,CAAC,CAAC,EAAE,OAAO,KAAK,GAAG,GACnB,OAAO,EACX,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC3B,UAAU,GAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,KAAK,OAA8B,EAC9D,QAAQ,CAAC,EAAE,GAAG,EAAE,cAOjB;AAED,wBAAgB,QAAQ,CACtB,aAAa,SAAS,SAAS,EAC/B,QAAQ,SAAS,CAAC,CAAC,EAAE,aAAa,KAAK,GAAG,EAE1C,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,aAAa,EACnC,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,QAAQ,SAAS,CAAC,CAAC,EAAE,aAAa,KAAK,MAAM,OAAO,GAC1D,CAAC,CAAC,EAAE,OAAO,KAAK,GAAG,GACnB,OAAO,EACX,UAAU,GAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,KAAK,OAA8B,cAyC/D"}
@@ -1,3 +1,2 @@
1
- export declare function selector(fn: () => any): () => void;
2
1
  export declare function useSelector<A>(fn: () => A): A;
3
2
  //# sourceMappingURL=selector.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"selector.d.ts","sourceRoot":"","sources":["../src/selector.tsx"],"names":[],"mappings":"AA4BA,wBAAgB,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,cAsCrC;AAED,wBAAgB,WAAW,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAsC7C"}
1
+ {"version":3,"file":"selector.d.ts","sourceRoot":"","sources":["../src/selector.tsx"],"names":[],"mappings":"AAqEA,wBAAgB,WAAW,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CA0C7C"}
@@ -1,17 +1,23 @@
1
- import { Selector, UseStoreOptions } from './interfaces';
2
- import { Store } from './Store';
3
- export declare function useStore<A extends Store<B>, B extends Object>(StoreKlass: (new (props: B) => A) | (new () => A), props?: B | null, options?: UseStoreOptions<A, any>): A;
4
- export declare function useStoreDebug<A extends Store<B>, B extends Object>(StoreKlass: (new (props: B) => A) | (new () => A), props?: B): A;
5
- export declare function createStore<A extends Store<B>, B extends Object>(StoreKlass: new (props: B) => A | (new () => A), props?: B, options?: UseStoreOptions<A, any>): A;
6
- export declare function useGlobalStore<A extends Store<B>, B extends Object>(instance: A, debug?: boolean): A;
7
- export declare function useGlobalStoreSelector<A extends Store<B>, B extends Object, Selector extends (store: A) => any>(instance: A, selector: Selector, debug?: boolean): Selector extends (a: A) => infer C ? C : unknown;
1
+ import { Selector, Store, StoreInfo, UseStoreOptions } from './interfaces';
2
+ export declare function useStore<A, B extends Object>(StoreKlass: (new (props: B) => A) | (new () => A), props?: B | null, options?: UseStoreOptions<A, any>): A;
3
+ export declare function useStoreDebug<A, B extends Object>(StoreKlass: (new (props: B) => A) | (new () => A), props?: B): A;
4
+ export declare function createStore<A, B extends Object>(StoreKlass: new (props: B) => A | (new () => A), props?: B, options?: UseStoreOptions<A, any>): A;
5
+ export declare function useGlobalStore<A, B extends Object>(instance: A, debug?: boolean): A;
6
+ export declare function useGlobalStoreSelector<A, Selector extends (store: A) => any>(instance: A, selector: Selector, debug?: boolean): Selector extends (a: A) => infer C ? C : unknown;
8
7
  export declare function createUseStore<Props, Store>(StoreKlass: (new (props: Props) => Store) | (new () => Store)): <Res, C extends Selector<Store, Res>, Props_1 extends Object>(props?: Props_1 | undefined, options?: UseStoreOptions) => C extends Selector<any, infer B> ? B extends Object ? B : Store : Store;
9
8
  export declare function createUseStoreSelector<A extends Store<Props>, Props extends Object, Selected>(StoreKlass: (new (props: Props) => A) | (new () => A), selector: Selector<A, Selected>): (props?: Props) => Selected;
10
9
  export declare function useStoreSelector<A extends Store<B>, B extends Object, S extends Selector<A, any>>(StoreKlass: (new (props: B) => A) | (new () => A), selector: S, props?: B): S extends Selector<any, infer R> ? R : unknown;
11
- type StoreAccessTracker = (store: any) => void;
10
+ type StoreAccessTracker = (store: StoreInfo) => void;
12
11
  export declare function trackStoresAccess(cb: StoreAccessTracker): () => void;
13
- export declare function getStore<A extends Store<B>, B extends Object>(StoreKlass: (new (props: B) => A) | (new () => A), props?: B): A;
12
+ export declare function getStore<A, B extends Object>(StoreKlass: (new (props: B) => A) | (new () => A), props?: B): A;
13
+ export declare function getStoreInfo(StoreKlass: any, props: any): StoreInfo;
14
14
  export declare const allStores: {};
15
15
  export declare const setIsInReaction: (val: boolean) => void;
16
+ export type StoreTracker = {
17
+ tracked: Set<string>;
18
+ component?: any;
19
+ last?: any;
20
+ lastKeys?: any;
21
+ };
16
22
  export {};
17
23
  //# sourceMappingURL=useStore.d.ts.map