bt-core-app 1.4.2 → 1.4.4

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.
Files changed (95) hide show
  1. package/dist/index.d.ts +1273 -41
  2. package/package.json +9 -2
  3. package/dist/composables/actions-tracker.d.ts +0 -19
  4. package/dist/composables/actions.d.ts +0 -79
  5. package/dist/composables/api.d.ts +0 -86
  6. package/dist/composables/auth.d.ts +0 -70
  7. package/dist/composables/cosmetics.d.ts +0 -38
  8. package/dist/composables/csv.d.ts +0 -20
  9. package/dist/composables/dates.d.ts +0 -15
  10. package/dist/composables/demo.d.ts +0 -9
  11. package/dist/composables/dialogs.d.ts +0 -75
  12. package/dist/composables/document-meta.d.ts +0 -11
  13. package/dist/composables/draggable.d.ts +0 -56
  14. package/dist/composables/filters.d.ts +0 -11
  15. package/dist/composables/forage.d.ts +0 -7
  16. package/dist/composables/helpers.d.ts +0 -100
  17. package/dist/composables/id.d.ts +0 -1
  18. package/dist/composables/list.d.ts +0 -211
  19. package/dist/composables/navigation.d.ts +0 -89
  20. package/dist/composables/presets.d.ts +0 -8
  21. package/dist/composables/pwa.d.ts +0 -14
  22. package/dist/composables/resizable.d.ts +0 -35
  23. package/dist/composables/rules.d.ts +0 -7
  24. package/dist/composables/stores.d.ts +0 -111
  25. package/dist/composables/track.d.ts +0 -12
  26. package/dist/composables/urls.d.ts +0 -22
  27. package/dist/core.d.ts +0 -19
  28. package/dist/types.d.ts +0 -13
  29. package/dist/useApi.d.ts +0 -0
  30. package/src/assets/vue.svg +0 -1
  31. package/src/components/BT-Btn.vue +0 -41
  32. package/src/components/BT-Col.vue +0 -36
  33. package/src/components/BT-Field-Checkbox.vue +0 -70
  34. package/src/components/BT-Field-Date.vue +0 -108
  35. package/src/components/BT-Field-Entity.vue +0 -48
  36. package/src/components/BT-Field-Select.vue +0 -67
  37. package/src/components/BT-Field-String.vue +0 -78
  38. package/src/components/BT-Field-Switch.vue +0 -68
  39. package/src/components/BT-Field-Tags.vue +0 -66
  40. package/src/components/BT-Field-Textarea.vue +0 -67
  41. package/src/components/BT-Field-Trigger.vue +0 -315
  42. package/src/components/BT-Header-Option.vue +0 -39
  43. package/src/components/BT-Json.vue +0 -67
  44. package/src/components/BT-Nav-Menu-Item.vue +0 -60
  45. package/src/components/BT-Nav-Sidebar.vue +0 -78
  46. package/src/components/BT-Select-List-Box.vue +0 -258
  47. package/src/components/BT-Select.vue +0 -46
  48. package/src/components/BT-Snack.vue +0 -31
  49. package/src/components/BT-Span.vue +0 -21
  50. package/src/components/Dialog-Confirm.vue +0 -47
  51. package/src/components/Dialog-Select-Date.vue +0 -89
  52. package/src/components/Dialog-Select.vue +0 -140
  53. package/src/components/Dialog-Text.vue +0 -59
  54. package/src/composables/actions-tracker.ts +0 -99
  55. package/src/composables/actions.ts +0 -354
  56. package/src/composables/api.ts +0 -479
  57. package/src/composables/auth.ts +0 -452
  58. package/src/composables/cosmetics.ts +0 -177
  59. package/src/composables/csv.ts +0 -198
  60. package/src/composables/dates.ts +0 -86
  61. package/src/composables/demo.ts +0 -33
  62. package/src/composables/dialogs.ts +0 -114
  63. package/src/composables/document-meta.ts +0 -44
  64. package/src/composables/draggable.ts +0 -189
  65. package/src/composables/filters.ts +0 -264
  66. package/src/composables/forage.ts +0 -49
  67. package/src/composables/helpers.ts +0 -647
  68. package/src/composables/id.ts +0 -20
  69. package/src/composables/list.ts +0 -604
  70. package/src/composables/navigation.ts +0 -222
  71. package/src/composables/presets.ts +0 -28
  72. package/src/composables/pwa.ts +0 -97
  73. package/src/composables/resizable.ts +0 -382
  74. package/src/composables/rules.ts +0 -40
  75. package/src/composables/stores.ts +0 -818
  76. package/src/composables/track.ts +0 -55
  77. package/src/composables/urls.ts +0 -66
  78. package/src/core.ts +0 -113
  79. package/src/index.ts +0 -48
  80. package/src/types.ts +0 -17
  81. package/src/useApi.ts +0 -68
  82. package/src/vite-env.d.ts +0 -1
  83. package/test/api.test.ts +0 -84
  84. package/test/auth.test.ts +0 -74
  85. package/test/forage.test.ts +0 -31
  86. package/test/helpers.test.ts +0 -231
  87. package/test/navigation.test.ts +0 -99
  88. package/test/stores-last-update.test.ts +0 -138
  89. package/test/stores-session.test.ts +0 -118
  90. package/test/track.test.ts +0 -29
  91. package/test/urls.test.ts +0 -42
  92. package/test/utils.ts +0 -15
  93. package/tsconfig.json +0 -28
  94. package/tsconfig.node.json +0 -11
  95. package/vite.config.ts +0 -45
@@ -1,818 +0,0 @@
1
- import { defineStore, Store, StoreDefinition } from 'pinia'
2
- import { ref, type Ref } from 'vue'
3
- import { type PathOptions, type BTApi } from '../composables/api'
4
- import { DateTime } from 'luxon'
5
- import { toValue } from 'vue'
6
- import { appendUrl, getMinDateString } from '../composables/helpers'
7
- import { firstBy } from 'thenby'
8
- import { useLocalDb } from '../composables/forage'
9
- import { BaseModel } from '../types'
10
- import { BTAuth } from './auth'
11
-
12
- export type StoreMode = 'whole-last-updated' | 'partial-last-updated' | 'session'
13
- export type StorageMode = 'session' | 'local-cache'
14
-
15
- export interface LocalMeta {
16
- storedOn: string //days
17
- isDetailed?: boolean
18
- earliestData?: string
19
- lastUpdate?: string
20
- }
21
-
22
- export interface LocallyStoredItem<T> {
23
- meta: LocalMeta,
24
- data: T,
25
- count?: number,
26
- filters?: string[]
27
- }
28
-
29
- export interface StoreGetAllReturn<T> {
30
- data: T[],
31
- count?: number,
32
- filters?: string[]
33
- }
34
-
35
- export interface StoreGetReturn<T> {
36
- data: T
37
- }
38
-
39
- export interface BTStoreDefinition extends StoreDefinition<any, {}, {},
40
- {
41
- deleteItem: (dOptions: PathOptions) => Promise<string | undefined>
42
- get: <T extends BaseModel>(dOptions: PathOptions) => Promise<StoreGetReturn<T>>
43
- getAll: <T extends BaseModel>(dOptions: PathOptions) => Promise<StoreGetAllReturn<T>>
44
- patch: <T extends BaseModel>(dOptions: PathOptions) => Promise<T | undefined>
45
- post: <T extends BaseModel>(dOptions: PathOptions) => Promise<T | undefined>
46
- restore: <T extends BaseModel>(dOptions: PathOptions) => Promise<T | undefined>
47
- }> {}
48
-
49
- export interface BTStore extends Store<any, {}, {}, {
50
- deleteItem: (dOptions: PathOptions) => Promise<string | undefined>
51
- get: <T extends BaseModel>(dOptions: PathOptions) => Promise<StoreGetReturn<T>>
52
- getAll: <T extends BaseModel>(dOptions: PathOptions) => Promise<StoreGetAllReturn<T>>
53
- patch: <T extends BaseModel>(dOptions: PathOptions) => Promise<T | undefined>
54
- post: <T extends BaseModel>(dOptions: PathOptions) => Promise<T | undefined>
55
- restore: <T extends BaseModel>(dOptions: PathOptions) => Promise<T | undefined>
56
- }> {}
57
-
58
- export interface ApiError {
59
- message: string
60
- }
61
-
62
- export interface UseStoreOptions {
63
- /**ideally required. Otherwise will struggle to find url path */
64
- api?: BTApi
65
- /**ideally required. For setting unique local storage keys */
66
- auth?: BTAuth
67
- /**build a query. Overrides the default */
68
- builderQuery?: (params: any) => string
69
- /**overrides the default */
70
- buildUrl?: (path: PathOptions) => string
71
- /**particularly what store syle to use */
72
- storeMode: StoreMode
73
- /**whether to store data locally or only for the duration of the session */
74
- storageMode: StorageMode
75
- /**the name of this store */
76
- storeName: string
77
- }
78
-
79
- export interface CreateStoreBuilderOptions {
80
- /**ideally required. Otherwise will struggle to find url path */
81
- api?: BTApi
82
- /**ideally required. For setting unique local storage keys */
83
- auth?: BTAuth
84
- /**build a query. Overrides the default */
85
- builderQuery?: (params: any) => string
86
- /**overrides the default */
87
- buildUrl?: (path: PathOptions) => string
88
- }
89
-
90
- export interface CreateStoreOptions {
91
- /**particularly what store syle to use */
92
- storeMode: StoreMode
93
- /**whether to store data locally or only for the duration of the session */
94
- storageMode: StorageMode
95
- /**the name of this store */
96
- storeName: string
97
- }
98
-
99
- let currentBuilder: (opt: CreateStoreOptions) => BTStoreDefinition
100
-
101
- export function useStore(options: CreateStoreOptions): BTStore {
102
- return currentBuilder(options)()
103
- }
104
-
105
- export function useStoreDefinition(options: CreateStoreOptions): BTStoreDefinition {
106
- return currentBuilder(options)
107
- }
108
-
109
- export function createStoreBuilder(options: CreateStoreBuilderOptions): (opt: CreateStoreOptions) => BTStoreDefinition {
110
- currentBuilder = (opt: CreateStoreOptions) => {
111
- return createStoreDefinition({
112
- ...options,
113
- ...opt
114
- })
115
- }
116
-
117
- return currentBuilder
118
- }
119
-
120
- export function createStoreDefinition(options: UseStoreOptions): BTStoreDefinition {
121
- if (options.storeMode == 'whole-last-updated') {
122
- if (options.api == null) throw new Error('Must supply an api object to use store')
123
-
124
- return createWholeLastUpdateStoreDefinition(options)
125
- }
126
- else if (options.storeMode == 'partial-last-updated') {
127
- if (options.api == null) throw new Error('Must supply an api object to use store')
128
-
129
- return createWholeLastUpdateStoreDefinition(options)
130
- }
131
- else { //if (options.storeMode == 'session') {
132
- return createSessionStoreDefinition(options)
133
- }
134
- }
135
-
136
- const defaultPathBuilder = (path: PathOptions) => {
137
- let url: string | undefined = toValue(path.url) ?? undefined
138
-
139
- if (path.additionalUrl != null) {
140
- if (url == null)
141
- url = path.additionalUrl
142
- else
143
- url = appendUrl(url, path.additionalUrl)
144
- }
145
-
146
- if (path.id != null) {
147
- if (url?.includes('{id}'))
148
- url = url.replaceAll('{id}', path.id)
149
- else
150
- url = appendUrl(url, path.id)
151
- }
152
-
153
- if (path.params != null) {
154
- url ??= ''
155
- let query = new URLSearchParams()
156
- let entries = Object.entries(path.params).sort(firstBy(x => x[0]))
157
- entries.forEach(entry => {
158
- if (entry[1] != null)
159
- query.append(entry[0], entry[1].toString())
160
- })
161
-
162
- url = `${url}?${query.toString()}`
163
- }
164
-
165
- path.finalUrl = url
166
-
167
- return path.finalUrl ?? ''
168
- }
169
-
170
- interface UseSessionStoreOptions {
171
- /**ideally required. Otherwise will struggle to find url path */
172
- api?: BTApi
173
- /**ideally required. For setting unique local storage keys */
174
- auth?: BTAuth
175
- /**whether to store data locally or only for the duration of the session */
176
- storageMode: 'session' | 'local-cache'
177
- /**build a query. Overrides the default */
178
- buildQuery?: (params: any) => string
179
- /**overrides the default */
180
- buildUrl?: (path: PathOptions) => string
181
- /**the name of this store */
182
- storeName: string
183
- }
184
-
185
- export function createSessionStoreDefinition(options: UseSessionStoreOptions): BTStoreDefinition {
186
- return defineStore(options.storeName, () => {
187
- const currentTimeStampDays = DateTime.utc().toSeconds() / 86400
188
- const searchMemory: Ref<any> = ref({})
189
- const promiseMemory: Ref<any> = ref({})
190
- const cacheLocally = options.storageMode == 'local-cache'
191
-
192
- const buildPath = options.buildUrl ?? options.api?.buildUrl ?? defaultPathBuilder
193
- // const authData = useAuthData()
194
-
195
- function getKey(dOptions: PathOptions) {
196
- return `${options.storeName}_${options.auth?.credentials.value.userID ?? 'no-user-id'}_${dOptions.id ?? dOptions.data?.id ?? 'no-item-id'}`
197
- }
198
-
199
- async function getAll<T extends BaseModel>(dOptions: PathOptions): Promise<StoreGetAllReturn<T>> {
200
- dOptions.additionalUrl ??= '/getAll'
201
-
202
- const path = buildPath(dOptions)
203
- const key = `${options.storeName}_${options.auth?.credentials.value.userID ?? 'no-user-id'}_${path}`
204
- const refresh = dOptions.refresh
205
-
206
- if (!refresh && searchMemory.value[key] !== undefined)
207
- return searchMemory.value[key] ?? null
208
-
209
- if (!refresh && cacheLocally == true) {
210
- //attempt to get locally
211
- const localRes = await useLocalDb().getItem<LocallyStoredItem<T[]>>(key)
212
-
213
- if (localRes != null &&
214
- (options.api == null || parseFloat(localRes.meta.storedOn) > (currentTimeStampDays - 7))) {
215
- searchMemory.value[key] = localRes
216
- return localRes
217
- }
218
- }
219
-
220
- //nothing exists in session so far so load from api
221
- if (options.api == null) {
222
- return searchMemory.value[key]
223
- }
224
-
225
- try {
226
- let apiPrm = promiseMemory.value[key]
227
-
228
- if (apiPrm == null) {
229
- apiPrm = new Promise<StoreGetAllReturn<T> | undefined>(async (resolve, reject) => {
230
- try {
231
- let res = await options.api?.getAll<StoreGetAllReturn<T>>(dOptions)
232
-
233
- if (cacheLocally == true) {
234
- await useLocalDb().setItem(key, {
235
- meta: { storedOn: currentTimeStampDays },
236
- ...res
237
- })
238
- }
239
-
240
- resolve(res)
241
- }
242
- catch (err) {
243
- reject(err)
244
- }
245
- finally {
246
- //remove promise
247
- delete promiseMemory.value[key]
248
- }
249
- })
250
-
251
- promiseMemory.value[key] = apiPrm
252
- }
253
-
254
- const apiRes = await apiPrm
255
-
256
- searchMemory.value[key] = apiRes
257
- return apiRes
258
- }
259
- catch (err) {
260
- let e = err as ApiError
261
- throw new Error(e.message ?? 'Problem')
262
- }
263
- }
264
-
265
- async function get<T extends BaseModel>(dOptions: PathOptions): Promise<StoreGetReturn<T>> {
266
- dOptions.additionalUrl ??= '/get'
267
-
268
- const key = getKey(dOptions)
269
- const refresh = dOptions.refresh
270
-
271
- if (!refresh && searchMemory.value[key] !== undefined)
272
- return searchMemory.value[key] ?? []
273
-
274
- if (!refresh && cacheLocally == true ) {
275
- //attempt to get locally
276
- const localRes = await useLocalDb().getItem<LocallyStoredItem<T>>(key)
277
-
278
- if (localRes != null &&
279
- (options.api == null || parseFloat(localRes.meta.storedOn) > (currentTimeStampDays - 7))) {
280
- searchMemory.value[key] = localRes
281
- return localRes
282
- }
283
- }
284
-
285
- //nothing exists in session so far so load from api
286
- if (options.api == null) {
287
- return searchMemory.value[key]
288
- }
289
-
290
- try {
291
- let apiPrm = promiseMemory.value[key]
292
-
293
- if (apiPrm == null) {
294
- apiPrm = new Promise(async (resolve, reject) => {
295
- try {
296
- let res = await options.api?.get<LocallyStoredItem<T>>(dOptions)
297
-
298
- if (cacheLocally == true) {
299
- await useLocalDb().setItem(key, {
300
- meta: { storedOn: currentTimeStampDays },
301
- ...res
302
- })
303
- }
304
-
305
- resolve(res)
306
- }
307
- catch (err) {
308
- reject(err)
309
- }
310
- finally {
311
- //remove promise
312
- delete promiseMemory.value[key]
313
- }
314
- })
315
-
316
- promiseMemory.value[key] = apiPrm
317
- }
318
-
319
- const apiRes = await apiPrm
320
- searchMemory.value[key] = apiRes
321
- return apiRes
322
- }
323
- catch (err) {
324
- let e = err as ApiError
325
- throw new Error(e.message ?? 'Problem')
326
- }
327
- }
328
-
329
- async function patch<T extends BaseModel>(dOptions: PathOptions): Promise<T | undefined> {
330
- dOptions.additionalUrl ??= '/patch'
331
-
332
- const key = getKey(dOptions)
333
- let patchedObject: any
334
-
335
- //patch api
336
- if (options.api != null) {
337
- //do not bother saving the promise
338
- try {
339
- let apiRes = await options.api.patch<StoreGetReturn<T>>(dOptions)
340
- patchedObject = apiRes?.data
341
- }
342
- catch (err) {
343
- let e = err as ApiError
344
- throw new Error(e.message ?? 'Patch Problem')
345
- }
346
- }
347
- else {
348
- patchedObject = dOptions.data
349
- }
350
-
351
- //update local versions
352
- if (patchedObject != null) {
353
- //update keyed search memory
354
- const existingItem = searchMemory.value[key]
355
- if (existingItem != null) {
356
- existingItem.data = { ...existingItem.data, ...patchedObject }
357
-
358
- //override local cache
359
- if (cacheLocally == true) {
360
- await useLocalDb().setItem(key, {
361
- meta: { storedOn: currentTimeStampDays },
362
- ...existingItem
363
- })
364
- }
365
- }
366
-
367
- //update other session stored items
368
- if (patchedObject.id != null && patchedObject.rowVersion != null) {
369
- let memoryItems = Object.entries(searchMemory.value)
370
- memoryItems.forEach(entry => {
371
- let entryVal = entry[1] as any
372
- entryVal = entryVal.data
373
- if (entryVal != null) {
374
- if (Array.isArray(entryVal)) {
375
- for (let i = 0; i < entryVal.length; i++) {
376
- const listItem = entryVal[i];
377
- if (listItem.id == patchedObject.id) {
378
- entryVal.splice(i, 1, { ...listItem, ...patchedObject})
379
- }
380
- }
381
- }
382
- else {
383
- if (entryVal.id == patchedObject.id) {
384
- searchMemory.value[entry[0]].data = { ...entryVal, ...patchedObject}
385
- }
386
- }
387
- }
388
- })
389
- }
390
- }
391
-
392
- return patchedObject
393
- }
394
-
395
- async function post<T extends BaseModel>(dOptions: PathOptions): Promise<T | undefined> {
396
- dOptions.additionalUrl ??= '/post'
397
-
398
- const key = getKey(dOptions)
399
- let postedObject: any
400
-
401
- //patch api
402
- if (options.api != null) {
403
- //do not bother saving the promise
404
- try {
405
- let apiRes = await options.api.post<StoreGetReturn<T>>(dOptions)
406
- postedObject = apiRes?.data
407
- }
408
- catch (err) {
409
- let e = err as ApiError
410
- throw new Error(e.message ?? 'Patch Problem')
411
- }
412
- }
413
- else {
414
- postedObject = dOptions.data
415
- }
416
-
417
- //update local versions
418
- searchMemory.value[key] = {
419
- meta: { storedOn: currentTimeStampDays },
420
- data: postedObject
421
- }
422
-
423
- if (cacheLocally == true) {
424
- await useLocalDb().setItem(key, searchMemory.value[key])
425
- }
426
-
427
- return postedObject
428
- }
429
-
430
- async function deleteItem(dOptions: PathOptions): Promise<string | undefined> {
431
- dOptions.additionalUrl ??= '/delete'
432
- const key = getKey(dOptions)
433
-
434
- //delete api
435
- if (options.api != null) {
436
- //do not bother saving the promise
437
- try {
438
- let res = await options.api.deleteItem(dOptions)
439
- if (res != null)
440
- return res
441
- }
442
- catch (err) {
443
- let e = err as ApiError
444
- throw new Error(e.message ?? 'Patch Problem')
445
- }
446
- }
447
-
448
- //delete local memory
449
- delete searchMemory.value[key]
450
-
451
- if (cacheLocally == true) {
452
- await useLocalDb().removeItem(key)
453
- }
454
-
455
- return undefined
456
- }
457
-
458
- async function restore<T extends BaseModel>(dOptions: PathOptions): Promise<T | undefined> {
459
- dOptions.additionalUrl ??= `/patch/restore?id=${dOptions.data.id}`
460
-
461
- buildPath(dOptions)
462
-
463
- //patch api
464
- if (options.api != null) {
465
- //do not bother saving the promise
466
- try {
467
- let apiRes = await options.api.patch<StoreGetReturn<T>>(dOptions)
468
- return apiRes?.data
469
- }
470
- catch (err) {
471
- let e = err as ApiError
472
- throw new Error(e.message ?? 'Patch Problem')
473
- }
474
- }
475
-
476
- return undefined
477
- }
478
-
479
- return {
480
- deleteItem,
481
- get,
482
- getAll,
483
- patch,
484
- post,
485
- restore,
486
- searchMemory //mainly for testing
487
- }
488
- })
489
- }
490
-
491
- interface UseWholeLastUpdateStoreOptions {
492
- /**ideally required. Otherwise will struggle to find url path */
493
- api?: BTApi
494
- /**ideally required. For setting unique local storage keys */
495
- auth?: BTAuth
496
- storageMode: 'session' | 'local-cache'
497
- storeName: string
498
- }
499
-
500
- export function createWholeLastUpdateStoreDefinition(options: UseWholeLastUpdateStoreOptions): BTStoreDefinition {
501
- return defineStore(options.storeName, () => {
502
- const dataItems: Ref<any[] | undefined> = ref()
503
- const count = ref(0)
504
- const currentTimeStampHours = DateTime.utc().toSeconds() / 3600
505
- const filters: Ref<string[] | undefined> = ref()
506
- const meta: Ref<LocalMeta | undefined> = ref()
507
- const promiseMemory: Ref<any> = ref({})
508
- const cacheLocally = options.storageMode == 'local-cache'
509
-
510
- function getKey() {
511
- return `${options.storeName}_${options.auth?.credentials.value.userID ?? 'no-user-id'}`
512
- }
513
-
514
- async function trySaveToLocalCache() {
515
- if (cacheLocally == true) {
516
- //save locally
517
- await useLocalDb().setItem(getKey(), {
518
- meta: meta.value,
519
- data: dataItems.value,
520
- count: count.value,
521
- filters: []
522
- })
523
- }
524
- }
525
-
526
- function createRefreshPromise<T extends BaseModel>(dOptions: PathOptions): Promise<StoreGetAllReturn<T>> {
527
- const key = getKey()
528
-
529
- if (promiseMemory.value[key])
530
- return promiseMemory.value[key]
531
-
532
- promiseMemory.value[key] = new Promise<StoreGetAllReturn<T>>(async (resolve, reject) => {
533
- try {
534
- let res = await options.api?.getAll<StoreGetAllReturn<T>>({
535
- additionalUrl: '/getAll',
536
- nav: dOptions.nav,
537
- params: {
538
- lastUpdate: meta.value?.lastUpdate ?? getMinDateString()
539
- }
540
- })
541
-
542
- if (res == null) {
543
- reject(res)
544
- }
545
- else {
546
- //update
547
- dataItems.value ??= []
548
- res.data.forEach(serverItem => {
549
- const existingInd = dataItems.value!.findIndex(x => x.id == serverItem.id)
550
- if (existingInd >= 0)
551
- dataItems.value?.splice(existingInd, 1, serverItem)
552
- else
553
- dataItems.value?.push(serverItem)
554
- })
555
-
556
- count.value = dataItems.value.length
557
- meta.value = {
558
- lastUpdate: DateTime.utc().toString(),
559
- storedOn: currentTimeStampHours.toString()
560
- }
561
-
562
- await trySaveToLocalCache()
563
-
564
- resolve(res)
565
- }
566
- }
567
- catch (err) {
568
- reject(err)
569
- }
570
- finally {
571
- //remove promise
572
- delete promiseMemory.value[key]
573
- }
574
- })
575
-
576
- return promiseMemory.value[key]
577
- }
578
-
579
- async function getAll<T extends BaseModel>(dOptions: PathOptions): Promise<StoreGetAllReturn<T>> {
580
- const key = getKey()
581
- const refresh = dOptions.refresh
582
- dOptions.nav ??= options.storeName
583
-
584
- if (!refresh && dataItems.value != null) {
585
- return {
586
- count: dataItems.value?.length,
587
- data: dataItems.value,
588
- filters: []
589
- }
590
- }
591
-
592
- if (!refresh && cacheLocally == true) {
593
- //retrieve from local cache
594
- const localRes = await useLocalDb().getItem<LocallyStoredItem<T[]>>(key)
595
-
596
- if (localRes != null &&
597
- parseFloat(localRes.meta.storedOn) > (currentTimeStampHours - 12)) {
598
- dataItems.value = localRes.data
599
- count.value = localRes.data.length
600
- filters.value = localRes.filters ?? []
601
- meta.value = localRes.meta
602
-
603
- return {
604
- count: dataItems.value?.length,
605
- data: dataItems.value,
606
- filters: []
607
- }
608
- }
609
- }
610
-
611
- //nothing exists in session so far so load from api
612
- if (options.api == null) {
613
- return {
614
- count: dataItems.value?.length,
615
- data: dataItems.value ?? [],
616
- filters: filters.value
617
- }
618
- }
619
- else {
620
- dataItems.value ??= []
621
- }
622
-
623
- try {
624
- return await createRefreshPromise(dOptions)
625
- }
626
- catch (err) {
627
- let e = err as ApiError
628
- throw new Error(e.message ?? 'Problem')
629
- }
630
- }
631
-
632
- async function get<T extends BaseModel>(dOptions: PathOptions): Promise<StoreGetReturn<T>> {
633
- const key = getKey()
634
- const refresh = dOptions.refresh
635
- dOptions.nav ??= options.storeName
636
-
637
- if (!refresh && dataItems.value != null) {
638
- return {
639
- data: dataItems.value.find(x => x.id == dOptions.id)
640
- }
641
- }
642
-
643
- if (!refresh && cacheLocally == true) {
644
- //retrieve from local cache
645
- const localRes = await useLocalDb().getItem<LocallyStoredItem<T[]>>(key)
646
-
647
- if (localRes != null &&
648
- parseFloat(localRes.meta.storedOn) > (currentTimeStampHours - 12)) {
649
- dataItems.value = localRes.data
650
- count.value = localRes.data.length
651
- filters.value = localRes.filters ?? []
652
- meta.value = localRes.meta
653
-
654
- let existingItem = dataItems.value.find(x => x.id == dOptions.id)
655
-
656
- if (existingItem != null)
657
- return { data: existingItem }
658
- }
659
- }
660
-
661
- if (options.api == null) {
662
- return {
663
- data: dataItems.value?.find(x => x.id == dOptions.id)
664
- }
665
- }
666
- else {
667
- dataItems.value ??= []
668
- }
669
-
670
- try {
671
- await createRefreshPromise<T>(dOptions)
672
-
673
- return { data: dataItems.value?.find(x => x.id == dOptions.id) }
674
- }
675
- catch (err) {
676
- let e = err as ApiError
677
- throw new Error(e.message ?? 'Problem')
678
- }
679
- }
680
-
681
- async function patch<T extends BaseModel>(dOptions: PathOptions): Promise<T | undefined> {
682
- dOptions.additionalUrl ??= '/patch'
683
- dOptions.nav ??= options.storeName
684
-
685
- let patchedObject: any
686
-
687
- //patch api
688
- if (options.api != null) {
689
- //do not bother saving the promise
690
- try {
691
- let apiRes = await options.api.patch<StoreGetReturn<T>>(dOptions)
692
- patchedObject = { ...dOptions.data, ...apiRes?.data }
693
- }
694
- catch (err) {
695
- let e = err as ApiError
696
- throw new Error(e.message ?? 'Patch Problem')
697
- }
698
- }
699
- else {
700
- patchedObject = dOptions.data
701
- }
702
-
703
- if (patchedObject != null) {
704
- let existingInd = dataItems.value?.findIndex(x => x.id == patchedObject.id)
705
- if (existingInd != null && existingInd >= 0) {
706
- dataItems.value ??= []
707
- dataItems.value?.splice(existingInd, 1, patchedObject)
708
- await trySaveToLocalCache()
709
- }
710
- }
711
-
712
- return dataItems.value?.find(x => x.id == (dOptions.id ?? dOptions.data.id))
713
- }
714
-
715
- async function post<T extends BaseModel>(dOptions: PathOptions): Promise<T | undefined> {
716
- dOptions.additionalUrl ??= '/post'
717
- dOptions.nav ??= options.storeName
718
-
719
- let postedObject: any
720
-
721
- //post api
722
- if (options.api != null) {
723
- //do not bother saving the promise
724
- try {
725
- let apiRes = await options.api.post<StoreGetReturn<T>>(dOptions)
726
- postedObject = apiRes?.data
727
- }
728
- catch (err) {
729
- let e = err as ApiError
730
- throw new Error(e.message ?? 'Patch Problem')
731
- }
732
- }
733
- else {
734
- postedObject = dOptions.data
735
- }
736
-
737
- if (postedObject != null) {
738
- dataItems.value ??= []
739
- dataItems.value?.unshift(postedObject)
740
- count.value += 1
741
- await trySaveToLocalCache()
742
- }
743
-
744
- return dataItems.value?.find(x => x.id == (dOptions.id ?? dOptions.data.id))
745
- }
746
-
747
- async function deleteItem(dOptions: PathOptions): Promise<string | undefined> {
748
- dOptions.additionalUrl ??= '/delete'
749
- dOptions.nav ??= options.storeName
750
-
751
- //delete api
752
- if (options.api != null) {
753
- //do not bother saving the promise
754
- try {
755
- let res = await options.api.deleteItem(dOptions)
756
- if (res != null)
757
- return res
758
- }
759
- catch (err) {
760
- let e = err as ApiError
761
- throw new Error(e.message ?? 'Patch Problem')
762
- }
763
- }
764
-
765
- const id = dOptions.id ?? dOptions.data.id
766
- if (id != null) {
767
- let existingInd = dataItems.value?.findIndex(x => x.id == id)
768
- if (existingInd != null && existingInd >= 0) {
769
- dataItems.value ??= []
770
- dataItems.value?.splice(existingInd, 1)
771
- await trySaveToLocalCache()
772
- }
773
- }
774
-
775
- return undefined
776
- }
777
-
778
- async function restore<T extends BaseModel>(dOptions: PathOptions): Promise<T | undefined> {
779
- dOptions.additionalUrl ??= `/patch/restore?id=${dOptions.data.id}`
780
- dOptions.nav ??= options.storeName
781
-
782
- //patch api
783
- if (options.api != null) {
784
- //do not bother saving the promise
785
- try {
786
- await options.api.patch<StoreGetReturn<T>>(dOptions)
787
- // let apiRes = await options.api.patch<StoreGetReturn<T>>(dOptions)
788
- // return apiRes?.data
789
- }
790
- catch (err) {
791
- let e = err as ApiError
792
- throw new Error(e.message ?? 'Patch Problem')
793
- }
794
- }
795
-
796
- //refresh
797
- try {
798
- dOptions.additionalUrl = '/getAll'
799
- await createRefreshPromise<any>(dOptions)
800
- }
801
- catch (err) {
802
- let e = err as ApiError
803
- throw new Error(e.message ?? 'Problem')
804
- }
805
-
806
- return dataItems.value?.find(x => x.id == (dOptions.id ?? dOptions.data.id))
807
- }
808
-
809
- return {
810
- deleteItem,
811
- get,
812
- getAll,
813
- patch,
814
- post,
815
- restore
816
- }
817
- })
818
- }