@data-weave/datamanager 0.3.8
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/CHANGELOG.md +50 -0
- package/lib/Cache.ts +41 -0
- package/lib/DataManager.ts +49 -0
- package/lib/List.ts +24 -0
- package/lib/LiveList.ts +70 -0
- package/lib/LiveReference.ts +57 -0
- package/lib/Reference.ts +34 -0
- package/lib/index.ts +6 -0
- package/lib/version.js +2 -0
- package/package.json +21 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Change Log
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
|
+
|
|
6
|
+
## [0.3.8](https://github.com/data-weave/datamanager/compare/v0.3.7...v0.3.8) (2025-09-28)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @data-weave/datamanager
|
|
9
|
+
|
|
10
|
+
## [0.3.7](https://github.com/data-weave/datamanager/compare/v0.3.6...v0.3.7) (2025-09-28)
|
|
11
|
+
|
|
12
|
+
**Note:** Version bump only for package @data-weave/datamanager
|
|
13
|
+
|
|
14
|
+
## [0.3.6](https://github.com/data-weave/datamanager/compare/v0.3.5...v0.3.6) (2025-09-28)
|
|
15
|
+
|
|
16
|
+
**Note:** Version bump only for package @data-weave/datamanager
|
|
17
|
+
|
|
18
|
+
## [0.3.5](https://github.com/data-weave/datamanager/compare/v0.3.4...v0.3.5) (2025-09-28)
|
|
19
|
+
|
|
20
|
+
**Note:** Version bump only for package @data-weave/datamanager
|
|
21
|
+
|
|
22
|
+
## [0.3.4](https://github.com/data-weave/datamanager/compare/v0.3.3...v0.3.4) (2025-09-28)
|
|
23
|
+
|
|
24
|
+
**Note:** Version bump only for package @data-weave/datamanager
|
|
25
|
+
|
|
26
|
+
## [0.3.2](https://github.com/data-weave/datamanager/compare/v0.3.1...v0.3.2) (2025-09-28)
|
|
27
|
+
|
|
28
|
+
**Note:** Version bump only for package @data-weave/datamanager
|
|
29
|
+
|
|
30
|
+
## [0.3.1](https://github.com/data-weave/datamanager/compare/v0.3.0...v0.3.1) (2025-09-28)
|
|
31
|
+
|
|
32
|
+
**Note:** Version bump only for package @data-weave/datamanager
|
|
33
|
+
|
|
34
|
+
## 0.3.0 (2025-09-28)
|
|
35
|
+
|
|
36
|
+
### Features
|
|
37
|
+
|
|
38
|
+
- add code quality workflow and circular dep check ([9c7b7e3](https://github.com/data-weave/datamanager/commit/9c7b7e34501dfc95ddc2bcff686f55db06d9b1b8))
|
|
39
|
+
- project re-organization ([4a00af3](https://github.com/data-weave/datamanager/commit/4a00af36c4c2f6e49287542e0d5ad85acaa50cda))
|
|
40
|
+
|
|
41
|
+
### Bug Fixes
|
|
42
|
+
|
|
43
|
+
- adjust config and lib versions ([9c7e2c9](https://github.com/data-weave/datamanager/commit/9c7e2c9072ea34b1e54326c2612b43c92ec2da4e))
|
|
44
|
+
- implement Cache prop & clean up some of anys ([955b11a](https://github.com/data-weave/datamanager/commit/955b11a6ab05224f843db834ad28796602679fac))
|
|
45
|
+
|
|
46
|
+
### Code Refactoring
|
|
47
|
+
|
|
48
|
+
- abstract out firestoreReference into LiveReference ([7848a87](https://github.com/data-weave/datamanager/commit/7848a872155593e5acab56696d4d9f27f0e6abb2))
|
|
49
|
+
- abstract out LiveList function from FirestorList ([bb4278e](https://github.com/data-weave/datamanager/commit/bb4278e960d0080d1fb18d847036acb189782ec9))
|
|
50
|
+
- adjustments for LiveList & ListReference ([49cd540](https://github.com/data-weave/datamanager/commit/49cd540295693e40bbb9eb75b5101b45c6932921))
|
package/lib/Cache.ts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export interface Cache<K = any, V = any> {
|
|
2
|
+
get(key: K): V | undefined
|
|
3
|
+
set(key: K, value: V): void
|
|
4
|
+
has(key: K): boolean
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export class MapCache<K, V> implements Cache<K, V> {
|
|
8
|
+
private cache = new Map<K, V>()
|
|
9
|
+
private maxSize?: number
|
|
10
|
+
|
|
11
|
+
constructor(maxSize?: number) {
|
|
12
|
+
this.maxSize = maxSize
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
get(key: K): V | undefined {
|
|
16
|
+
return this.cache.get(key)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
set(key: K, value: V): void {
|
|
20
|
+
if (this.maxSize && this.cache.size >= this.maxSize && !this.cache.has(key)) {
|
|
21
|
+
// Remove the first entry (oldest) when cache is full
|
|
22
|
+
const firstKey = this.cache.keys().next().value
|
|
23
|
+
if (firstKey) {
|
|
24
|
+
this.cache.delete(firstKey)
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
this.cache.set(key, value)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
has(key: K): boolean {
|
|
31
|
+
return this.cache.has(key)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
delete(key: K): boolean {
|
|
35
|
+
return this.cache.delete(key)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
clear(): void {
|
|
39
|
+
this.cache.clear()
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { List } from './List'
|
|
2
|
+
import { IdentifiableReference, WithoutId } from './Reference'
|
|
3
|
+
|
|
4
|
+
export interface ReadOptions {
|
|
5
|
+
readonly transaction?: unknown
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface WriteOptions {
|
|
9
|
+
readonly transaction?: unknown
|
|
10
|
+
readonly batcher?: unknown
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface CreateOptions extends WriteOptions {
|
|
14
|
+
id?: string
|
|
15
|
+
merge?: boolean
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export type OrderByOption = 'asc' | 'desc'
|
|
19
|
+
|
|
20
|
+
export interface GetListOptions {
|
|
21
|
+
readonly filterBy?: unknown
|
|
22
|
+
readonly orderBy?: unknown
|
|
23
|
+
readonly limit?: number
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface Metadata {
|
|
27
|
+
readonly id: string
|
|
28
|
+
readonly createdAt: Date
|
|
29
|
+
readonly updatedAt: Date
|
|
30
|
+
readonly deleted: boolean
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Copy of Firestore DocumentData definition
|
|
34
|
+
type DocumentData = {
|
|
35
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
36
|
+
[field: string]: any
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export type WithMetadata<T extends DocumentData> = T & Metadata
|
|
40
|
+
export abstract class DataManager<T extends DocumentData> {
|
|
41
|
+
public abstract read(id: string): Promise<T | undefined>
|
|
42
|
+
public abstract create(data: WithoutId<T>, options?: CreateOptions): Promise<IdentifiableReference<WithMetadata<T>>>
|
|
43
|
+
public abstract delete(id: string): Promise<void>
|
|
44
|
+
public abstract update(id: string, data: Partial<WithoutId<T>>): Promise<void>
|
|
45
|
+
public abstract upsert(id: string, data: WithoutId<T>): Promise<void>
|
|
46
|
+
|
|
47
|
+
public abstract getRef(id: string): IdentifiableReference<WithMetadata<T>>
|
|
48
|
+
public abstract getList(params?: GetListOptions): List<WithMetadata<T>>
|
|
49
|
+
}
|
package/lib/List.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Resolvable } from './Reference'
|
|
2
|
+
|
|
3
|
+
export interface ListPaginationParams {
|
|
4
|
+
readonly pageSize?: number
|
|
5
|
+
readonly append?: boolean
|
|
6
|
+
readonly loadFirstPageManually?: boolean
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface List<T> extends Resolvable<readonly T[]> {
|
|
10
|
+
readonly values: readonly T[]
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function createInitializedList<T>(values: ReadonlyArray<T>): List<T> {
|
|
14
|
+
return {
|
|
15
|
+
values,
|
|
16
|
+
resolved: true,
|
|
17
|
+
hasError: false,
|
|
18
|
+
resolve: async () => values,
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function createEmptyList<T>(): List<T> {
|
|
23
|
+
return createInitializedList([])
|
|
24
|
+
}
|
package/lib/LiveList.ts
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { List } from './List'
|
|
2
|
+
|
|
3
|
+
export interface LiveListOptions<T> {
|
|
4
|
+
onUpdate?: (newValues: T[]) => void
|
|
5
|
+
onError?: (error: unknown) => void
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export class LiveList<T> implements List<T> {
|
|
9
|
+
private _values: T[] = []
|
|
10
|
+
private _resolved: boolean = false
|
|
11
|
+
private _hasError: boolean = false
|
|
12
|
+
private _options: LiveListOptions<T>
|
|
13
|
+
|
|
14
|
+
constructor(options: LiveListOptions<T>) {
|
|
15
|
+
this._options = options
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
resolve(): Promise<readonly T[]> {
|
|
19
|
+
throw new Error('Method not implemented.')
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
public get values() {
|
|
23
|
+
return this._values
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
public get hasError() {
|
|
27
|
+
return this._hasError
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
public get resolved() {
|
|
31
|
+
return this._resolved
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
protected setStale() {
|
|
35
|
+
this._resolved = false
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
protected onValuesChange(): void {}
|
|
39
|
+
|
|
40
|
+
protected onUpdate(): void {
|
|
41
|
+
this._resolved = true
|
|
42
|
+
this.onValuesChange()
|
|
43
|
+
this._options.onUpdate?.(this._values)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
protected onUpdateAll(values: T[]): void {
|
|
47
|
+
this._values = values
|
|
48
|
+
this.onUpdate()
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
protected onUpdateAtIndex(index: number, value: T): void {
|
|
52
|
+
this._values[index] = value
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
protected onAddAtIndex(index: number, value: T): void {
|
|
56
|
+
this._values.splice(index, 0, value)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
protected onRemoveAtIndex(index: number): void {
|
|
60
|
+
this._values.splice(index, 1)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
protected onError(error: unknown): void {
|
|
64
|
+
this._hasError = true
|
|
65
|
+
this._values = []
|
|
66
|
+
this._resolved = true
|
|
67
|
+
this._options.onError?.(error)
|
|
68
|
+
this.onValuesChange()
|
|
69
|
+
}
|
|
70
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { Reference } from './Reference'
|
|
2
|
+
|
|
3
|
+
export interface LiveReferenceOptions<T> {
|
|
4
|
+
onUpdate?: (newValue: T | undefined) => void
|
|
5
|
+
onError?: (error: unknown) => void
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export class LiveReference<T> implements Reference<T> {
|
|
9
|
+
private _value: T | undefined
|
|
10
|
+
private _resolved: boolean = false
|
|
11
|
+
private _hasError: boolean = false
|
|
12
|
+
private _options: LiveReferenceOptions<T>
|
|
13
|
+
|
|
14
|
+
resolve(): Promise<T | undefined> {
|
|
15
|
+
throw new Error('Method not implemented.')
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
constructor(readonly options: LiveReferenceOptions<T>) {
|
|
19
|
+
this._value = undefined
|
|
20
|
+
this._resolved = false
|
|
21
|
+
this._hasError = false
|
|
22
|
+
this._options = options
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
public get value(): T | undefined {
|
|
26
|
+
return this._value
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
public get resolved() {
|
|
30
|
+
return this._resolved
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
public get hasError() {
|
|
34
|
+
return this._hasError
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
protected setStale() {
|
|
38
|
+
this._resolved = false
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
protected onUpdate(data: T | undefined): void {
|
|
42
|
+
this._value = data
|
|
43
|
+
this._resolved = true
|
|
44
|
+
this.onValueChange()
|
|
45
|
+
this._options.onUpdate?.(this._value)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
protected onError(error: unknown) {
|
|
49
|
+
this._hasError = true
|
|
50
|
+
this._value = undefined
|
|
51
|
+
this._resolved = true
|
|
52
|
+
this.onValueChange()
|
|
53
|
+
this._options.onError?.(error)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
protected onValueChange(): void {}
|
|
57
|
+
}
|
package/lib/Reference.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export interface Identifiable {
|
|
2
|
+
readonly id: string
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export type WithoutId<T> = Omit<T, 'id'>
|
|
6
|
+
|
|
7
|
+
export interface Resolvable<T> {
|
|
8
|
+
readonly resolved: boolean
|
|
9
|
+
readonly hasError: boolean
|
|
10
|
+
resolve(): Promise<T>
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface Reference<T> extends Resolvable<T | undefined> {
|
|
14
|
+
readonly value: T | undefined
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export type IdentifiableReference<T> = Reference<T> & Identifiable
|
|
18
|
+
|
|
19
|
+
export function createInitializedIdentifiableReference<T>(
|
|
20
|
+
value: T | undefined,
|
|
21
|
+
id: string
|
|
22
|
+
): Reference<T> & Identifiable {
|
|
23
|
+
return {
|
|
24
|
+
id,
|
|
25
|
+
value,
|
|
26
|
+
resolved: true,
|
|
27
|
+
hasError: false,
|
|
28
|
+
resolve: async () => value,
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function createEmptyIdentifiableReference<T>(id: string): Reference<T> {
|
|
33
|
+
return createInitializedIdentifiableReference<T>(undefined, id)
|
|
34
|
+
}
|
package/lib/index.ts
ADDED
package/lib/version.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@data-weave/datamanager",
|
|
3
|
+
"version": "0.3.8",
|
|
4
|
+
"author": "",
|
|
5
|
+
"main": "lib/index.js",
|
|
6
|
+
"types": "lib/index.d.ts",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"build": "genversion --semi lib/version.js",
|
|
9
|
+
"build:clean": "rimraf android/build && rimraf ios/build",
|
|
10
|
+
"prepare": "npm run build"
|
|
11
|
+
},
|
|
12
|
+
"repository": {
|
|
13
|
+
"type": "git",
|
|
14
|
+
"url": "https://github.com/data-weave/datamanager/tree/master/packages/datamanager"
|
|
15
|
+
},
|
|
16
|
+
"publishConfig": {
|
|
17
|
+
"access": "public",
|
|
18
|
+
"registry": "https://registry.npmjs.org/"
|
|
19
|
+
},
|
|
20
|
+
"gitHead": "15240bc24e96bab7e184edd81f18fbf64b52d8c9"
|
|
21
|
+
}
|