teamplay 0.4.0-alpha.0 → 0.4.0-alpha.10

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/index.d.ts CHANGED
@@ -28,6 +28,8 @@ export function observer<
28
28
 
29
29
  // Keep existing public surface available even if typed loosely for now.
30
30
  export const $: any
31
+ export const $root: any
32
+ export const model: any
31
33
  export { default as Signal, SEGMENTS } from './orm/Signal.js'
32
34
  export { __DEBUG_SIGNALS_CACHE__, rawSignal, getSignalClass } from './orm/getSignal.js'
33
35
  export { default as addModel } from './orm/addModel.js'
@@ -40,6 +42,57 @@ export {
40
42
  setUseDeferredValue as __setUseDeferredValue,
41
43
  setDefaultDefer as __setDefaultDefer
42
44
  } from './react/useSub.js'
45
+ export function useValue (defaultValue?: any): [any, any]
46
+ export function useValue$ (defaultValue?: any): any
47
+ export function useModel (path?: any): any
48
+ export function useLocal (path?: any): [any, any]
49
+ export function useLocal$ (path?: any): any
50
+ export function useSession (path?: any): [any, any]
51
+ export function useSession$ (path?: any): any
52
+ export function usePage (path?: any): [any, any]
53
+ export function usePage$ (path?: any): any
54
+ export function useBatch (): void
55
+ export function useDoc (collection: string, id: any, options?: any): [any, any]
56
+ export function useDoc$ (collection: string, id: any, options?: any): any
57
+ export function useBatchDoc (collection: string, id: any, options?: any): [any, any]
58
+ export function useBatchDoc$ (collection: string, id: any, options?: any): any
59
+ export function useAsyncDoc (collection: string, id: any, options?: any): [any, any]
60
+ export function useAsyncDoc$ (collection: string, id: any, options?: any): any
61
+ export function useQuery (collection: string, query: any, options?: any): [any, any]
62
+ export function useQuery$ (collection: string, query: any, options?: any): any
63
+ export function useAsyncQuery (collection: string, query: any, options?: any): [any, any]
64
+ export function useAsyncQuery$ (collection: string, query: any, options?: any): any
65
+ export function useBatchQuery (collection: string, query: any, options?: any): [any, any]
66
+ export function useBatchQuery$ (collection: string, query: any, options?: any): any
67
+ export function useQueryIds (collection: string, ids?: any[], options?: any): [any, any]
68
+ export function useBatchQueryIds (collection: string, ids?: any[], options?: any): [any, any]
69
+ export function useAsyncQueryIds (collection: string, ids?: any[], options?: any): [any, any]
70
+ export function useQueryDoc (collection: string, query: any, options?: any): [any, any]
71
+ export function useQueryDoc$ (collection: string, query: any, options?: any): any
72
+ export function useBatchQueryDoc (collection: string, query: any, options?: any): [any, any]
73
+ export function useBatchQueryDoc$ (collection: string, query: any, options?: any): any
74
+ export function useAsyncQueryDoc (collection: string, query: any, options?: any): [any, any]
75
+ export function useAsyncQueryDoc$ (collection: string, query: any, options?: any): any
76
+ export function useLocalDoc (collection: string, id: any): [any, any]
77
+ export function useLocalDoc$ (collection: string, id: any): any
78
+ export function emit (eventName: string, ...args: any[]): void
79
+ export function useOn (
80
+ eventName: 'change' | 'all',
81
+ pattern: string | { path: () => string },
82
+ handler: (...args: any[]) => void,
83
+ deps?: any[]
84
+ ): void
85
+ export function useOn (eventName: string, handler: (...args: any[]) => void, deps?: any[]): void
86
+ export function useEmit (): (eventName: string, ...args: any[]) => void
87
+ export function batch<T = any> (fn?: () => T): T | undefined
88
+ export function batchModel<T = any> (fn?: () => T): T | undefined
89
+ export function clone<T = any> (value: T): T
90
+ export function initLocalCollection (name: string): any
91
+ export function useApi (api: (...args: any[]) => any, args?: any[], options?: { debounce?: number }): [any, boolean, any]
92
+ type EffectCleanup = (() => void) | undefined
93
+ export function useDidUpdate (fn: () => EffectCleanup, deps?: any[]): void
94
+ export function useOnce (condition: any, fn: () => EffectCleanup): void
95
+ export function useSyncEffect (fn: () => EffectCleanup, deps?: any[]): void
43
96
  export { connection, setConnection, getConnection, fetchOnly, setFetchOnly, publicOnly, setPublicOnly } from './orm/connection.js'
44
97
  export { useId, useNow, useScheduleUpdate, useTriggerUpdate } from './react/helpers.js'
45
98
  export { GUID_PATTERN, hasMany, hasOne, hasManyFlags, belongsTo, pickFormFields } from '@teamplay/schema'
package/index.js CHANGED
@@ -5,6 +5,7 @@
5
5
  // In future, we might want to separate the plain JS and React APIs
6
6
  import { getRootSignal as _getRootSignal, GLOBAL_ROOT_ID } from './orm/Root.js'
7
7
  import universal$ from './react/universal$.js'
8
+ import useApi from './react/useApi.js'
8
9
 
9
10
  export { default as Signal, SEGMENTS } from './orm/Signal.js'
10
11
  export { __DEBUG_SIGNALS_CACHE__, rawSignal, getSignalClass } from './orm/getSignal.js'
@@ -12,6 +13,8 @@ export { default as addModel } from './orm/addModel.js'
12
13
  export { default as signal } from './orm/getSignal.js'
13
14
  export { GLOBAL_ROOT_ID } from './orm/Root.js'
14
15
  export const $ = _getRootSignal({ rootId: GLOBAL_ROOT_ID, rootFunction: universal$ })
16
+ export const $root = $
17
+ export const model = $
15
18
  export default $
16
19
  export { default as sub } from './orm/sub.js'
17
20
  export {
@@ -21,12 +24,86 @@ export {
21
24
  setDefaultDefer as __setDefaultDefer
22
25
  } from './react/useSub.js'
23
26
  export { default as observer } from './react/observer.js'
27
+ export {
28
+ useValue,
29
+ useValue$,
30
+ useModel,
31
+ useLocal,
32
+ useLocal$,
33
+ useLocalDoc,
34
+ useLocalDoc$,
35
+ useSession,
36
+ useSession$,
37
+ usePage,
38
+ usePage$,
39
+ useBatch,
40
+ useDoc,
41
+ useDoc$,
42
+ useBatchDoc,
43
+ useBatchDoc$,
44
+ useAsyncDoc,
45
+ useAsyncDoc$,
46
+ useQuery,
47
+ useQuery$,
48
+ useAsyncQuery,
49
+ useAsyncQuery$,
50
+ useBatchQuery,
51
+ useBatchQuery$,
52
+ useQueryIds,
53
+ useBatchQueryIds,
54
+ useAsyncQueryIds,
55
+ useQueryDoc,
56
+ useQueryDoc$,
57
+ useBatchQueryDoc,
58
+ useBatchQueryDoc$,
59
+ useAsyncQueryDoc,
60
+ useAsyncQueryDoc$
61
+ } from './orm/Compat/hooksCompat.js'
62
+ export { emit, useOn, useEmit } from './orm/Compat/eventsCompat.js'
63
+ export {
64
+ useDidUpdate,
65
+ useOnce,
66
+ useSyncEffect
67
+ } from './react/helpers.js'
24
68
  export { connection, setConnection, getConnection, fetchOnly, setFetchOnly, publicOnly, setPublicOnly } from './orm/connection.js'
25
69
  export { useId, useNow, useScheduleUpdate, useTriggerUpdate } from './react/helpers.js'
26
70
  export { GUID_PATTERN, hasMany, hasOne, hasManyFlags, belongsTo, pickFormFields } from '@teamplay/schema'
27
71
  export { aggregation, aggregationHeader as __aggregationHeader } from '@teamplay/utils/aggregation'
28
72
  export { accessControl } from '@teamplay/utils/accessControl'
29
73
 
74
+ export function batch (fn) {
75
+ return $.batch(fn)
76
+ }
77
+
78
+ export function batchModel (fn) {
79
+ return $.batch(fn)
80
+ }
81
+
82
+ export function clone (value) {
83
+ if (typeof globalThis.structuredClone === 'function') {
84
+ try {
85
+ return globalThis.structuredClone(value)
86
+ } catch {}
87
+ }
88
+ if (value == null) return value
89
+ return JSON.parse(JSON.stringify(value))
90
+ }
91
+
92
+ export function initLocalCollection (name) {
93
+ if (typeof name !== 'string') throw Error('initLocalCollection() expects a collection name')
94
+ if (!name) return
95
+ const segments = name.split('.').filter(Boolean)
96
+ if (!segments.length) return
97
+ let $cursor = $
98
+ for (const segment of segments) {
99
+ $cursor = $cursor[segment]
100
+ }
101
+ if ($cursor.get() == null) $cursor.set({})
102
+ return $cursor
103
+ }
104
+
105
+ export { useApi }
106
+
30
107
  export function getRootSignal (options) {
31
108
  return _getRootSignal({
32
109
  rootFunction: universal$,
@@ -3,6 +3,7 @@ import { set as _set, del as _del, getRaw } from './dataTree.js'
3
3
  import getSignal from './getSignal.js'
4
4
  import { QuerySubscriptions, hashQuery, Query, HASH, PARAMS, COLLECTION_NAME, parseQueryHash } from './Query.js'
5
5
  import Signal, { SEGMENTS } from './Signal.js'
6
+ import { getIdFieldsForSegments, isPlainObject } from './idFields.js'
6
7
 
7
8
  export const IS_AGGREGATION = Symbol('is aggregation signal')
8
9
  export const AGGREGATIONS = '$aggregations'
@@ -11,11 +12,13 @@ class Aggregation extends Query {
11
12
  _initData () {
12
13
  {
13
14
  const extra = raw(this.shareQuery.extra)
15
+ injectAggregationIds(extra, this.collectionName)
14
16
  _set([AGGREGATIONS, this.hash], extra)
15
17
  }
16
18
 
17
19
  this.shareQuery.on('extra', extra => {
18
20
  extra = raw(extra)
21
+ injectAggregationIds(extra, this.collectionName)
19
22
  _set([AGGREGATIONS, this.hash], extra)
20
23
  })
21
24
  }
@@ -27,6 +30,18 @@ class Aggregation extends Query {
27
30
 
28
31
  export const aggregationSubscriptions = new QuerySubscriptions(Aggregation)
29
32
 
33
+ function injectAggregationIds (extra, collectionName) {
34
+ if (!Array.isArray(extra)) return
35
+ const idFields = getIdFieldsForSegments([collectionName, ''])
36
+ for (const doc of extra) {
37
+ if (!isPlainObject(doc)) continue
38
+ const docId = doc._id ?? doc.id
39
+ if (docId == null) continue
40
+ if (idFields.includes('_id') && doc._id !== docId) doc._id = docId
41
+ if (idFields.includes('id') && doc.id !== docId) doc.id = docId
42
+ }
43
+ }
44
+
30
45
  export function getAggregationSignal (collectionName, params, options) {
31
46
  params = JSON.parse(JSON.stringify(params))
32
47
  const hash = hashQuery(collectionName, params)