entropic-bond 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/lib/auth/auth-mock.d.ts +22 -0
- package/lib/auth/auth-mock.spec.d.ts +1 -0
- package/lib/auth/auth.d.ts +131 -0
- package/lib/auth/user-auth-types.d.ts +19 -0
- package/lib/cloud-functions/cloud-functions-mock.d.ts +11 -0
- package/lib/cloud-functions/cloud-functions-mock.spec.d.ts +1 -0
- package/lib/cloud-functions/cloud-functions.d.ts +19 -0
- package/lib/cloud-storage/cloud-storage.d.ts +24 -0
- package/lib/cloud-storage/cloud-storage.spec.d.ts +1 -0
- package/lib/cloud-storage/mock-cloud-storage.d.ts +20 -0
- package/lib/cloud-storage/stored-file.d.ts +39 -0
- package/lib/entropic-bond.js +1667 -0
- package/lib/entropic-bond.umd.cjs +7 -0
- package/lib/index.d.ts +19 -0
- package/lib/observable/observable.d.ts +52 -0
- package/lib/observable/observable.spec.d.ts +1 -0
- package/lib/persistent/entropic-component.d.ts +76 -0
- package/lib/persistent/entropic-component.spec.d.ts +1 -0
- package/lib/persistent/persistent.d.ts +281 -0
- package/lib/persistent/persistent.spec.d.ts +67 -0
- package/lib/server-auth/server-auth-mock.d.ts +12 -0
- package/lib/server-auth/server-auth-mock.spec.d.ts +1 -0
- package/lib/server-auth/server-auth.d.ts +24 -0
- package/lib/store/data-source.d.ts +137 -0
- package/lib/store/json-data-source.d.ts +68 -0
- package/lib/store/json-data-source.spec.d.ts +1 -0
- package/lib/store/mocks/test-user.d.ts +49 -0
- package/lib/store/model.d.ts +238 -0
- package/lib/store/model.spec.d.ts +1 -0
- package/lib/store/store.d.ts +62 -0
- package/lib/store/store.spec.d.ts +1 -0
- package/lib/types/utility-types.d.ts +45 -0
- package/lib/types/utility-types.spec.d.ts +1 -0
- package/lib/utils/test-utils/test-person.d.ts +33 -0
- package/{src/utils/utils.ts → lib/utils/utils.d.ts} +10 -34
- package/lib/utils/utils.spec.d.ts +1 -0
- package/package.json +7 -4
- package/.github/workflows/release.yml +0 -26
- package/CHANGELOG.md +0 -1151
- package/docs/.nojekyll +0 -1
- package/docs/README.md +0 -94
- package/docs/classes/Auth.md +0 -391
- package/docs/classes/AuthMock.md +0 -278
- package/docs/classes/AuthService.md +0 -188
- package/docs/classes/CloudFunctions.md +0 -123
- package/docs/classes/CloudFunctionsMock.md +0 -97
- package/docs/classes/CloudStorage.md +0 -215
- package/docs/classes/DataSource.md +0 -248
- package/docs/classes/EntropicComponent.md +0 -666
- package/docs/classes/JsonDataSource.md +0 -328
- package/docs/classes/MockCloudStorage.md +0 -279
- package/docs/classes/Model.md +0 -274
- package/docs/classes/Observable.md +0 -120
- package/docs/classes/Persistent.md +0 -420
- package/docs/classes/ServerAuth.md +0 -211
- package/docs/classes/ServerAuthMock.md +0 -176
- package/docs/classes/ServerAuthService.md +0 -130
- package/docs/classes/Store.md +0 -218
- package/docs/classes/StoredFile.md +0 -636
- package/docs/enums/StoredFileEvent.md +0 -41
- package/docs/interfaces/AuthError.md +0 -30
- package/docs/interfaces/CloudFunctionsService.md +0 -69
- package/docs/interfaces/Collection.md +0 -13
- package/docs/interfaces/CustomCredentials.md +0 -7
- package/docs/interfaces/DocumentReference.md +0 -49
- package/docs/interfaces/JsonRawData.md +0 -7
- package/docs/interfaces/SignData.md +0 -63
- package/docs/interfaces/StoreParams.md +0 -52
- package/docs/interfaces/StoredFileChange.md +0 -41
- package/docs/interfaces/UploadControl.md +0 -90
- package/docs/interfaces/UserCredentials.md +0 -113
- package/docs/interfaces/Values.md +0 -17
- package/docs/modules.md +0 -1273
- package/src/auth/auth-mock.spec.ts +0 -168
- package/src/auth/auth-mock.ts +0 -129
- package/src/auth/auth.ts +0 -185
- package/src/auth/user-auth-types.ts +0 -21
- package/src/cloud-functions/cloud-functions-mock.spec.ts +0 -136
- package/src/cloud-functions/cloud-functions-mock.ts +0 -23
- package/src/cloud-functions/cloud-functions.ts +0 -83
- package/src/cloud-storage/cloud-storage.spec.ts +0 -207
- package/src/cloud-storage/cloud-storage.ts +0 -60
- package/src/cloud-storage/mock-cloud-storage.ts +0 -72
- package/src/cloud-storage/stored-file.ts +0 -102
- package/src/index.ts +0 -19
- package/src/observable/observable.spec.ts +0 -105
- package/src/observable/observable.ts +0 -67
- package/src/persistent/entropic-component.spec.ts +0 -143
- package/src/persistent/entropic-component.ts +0 -135
- package/src/persistent/persistent.spec.ts +0 -828
- package/src/persistent/persistent.ts +0 -650
- package/src/server-auth/server-auth-mock.spec.ts +0 -53
- package/src/server-auth/server-auth-mock.ts +0 -45
- package/src/server-auth/server-auth.ts +0 -49
- package/src/store/data-source.ts +0 -186
- package/src/store/json-data-source.spec.ts +0 -100
- package/src/store/json-data-source.ts +0 -256
- package/src/store/mocks/mock-data.json +0 -155
- package/src/store/mocks/test-user.ts +0 -122
- package/src/store/model.spec.ts +0 -659
- package/src/store/model.ts +0 -462
- package/src/store/store.spec.ts +0 -30
- package/src/store/store.ts +0 -113
- package/src/types/utility-types.spec.ts +0 -117
- package/src/types/utility-types.ts +0 -116
- package/src/utils/test-utils/test-person.ts +0 -44
- package/src/utils/utils.spec.ts +0 -95
- package/tsconfig-build.json +0 -7
- package/tsconfig-cjs.json +0 -9
- package/tsconfig.json +0 -33
- package/vite.config.ts +0 -22
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
import { Persistent, PersistentObject } from '../persistent/persistent'
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
export type CloudFunction<P,R> = ( param?: P) => Promise<R>
|
|
5
|
-
|
|
6
|
-
export interface CloudFunctionsService {
|
|
7
|
-
retrieveFunction<P, R>( cloudFunction: string ): CloudFunction<P, R>
|
|
8
|
-
callFunction<P,R>( func: CloudFunction<P, R>, params: P ): Promise<R>
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export class CloudFunctions {
|
|
12
|
-
private constructor() {}
|
|
13
|
-
|
|
14
|
-
static error = { shouldBeRegistered: 'You should register a cloud functions service with useCloudFunctionsService static method before using CloudFunctions.' }
|
|
15
|
-
|
|
16
|
-
static useCloudFunctionsService( cloudFunctionsService: CloudFunctionsService ) {
|
|
17
|
-
if ( this._cloudFunctionsService != cloudFunctionsService ) {
|
|
18
|
-
this._cloudFunctionsService = cloudFunctionsService
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
static get instance() {
|
|
23
|
-
if ( !this._cloudFunctionsService ) throw new Error( CloudFunctions.error.shouldBeRegistered )
|
|
24
|
-
return CloudFunctions._instance || ( CloudFunctions._instance = new CloudFunctions() )
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
getRawFunction<P, R>( cloudFunction: string ): CloudFunction<P,R> {
|
|
28
|
-
return CloudFunctions._cloudFunctionsService.retrieveFunction( cloudFunction )
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
getFunction<P, R=void>( cloudFunction: string ): CloudFunction<P,R> {
|
|
32
|
-
const callFunction = CloudFunctions._cloudFunctionsService.callFunction
|
|
33
|
-
const func = this.getRawFunction<P, R>( cloudFunction )
|
|
34
|
-
|
|
35
|
-
return async ( param: P ) => {
|
|
36
|
-
const result = await callFunction( func, this.processParam( param ) )
|
|
37
|
-
return this.processResult( result )
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
private processParam<P>( param: P ): P | PersistentObject<P & Persistent> {
|
|
42
|
-
if ( param === undefined || param === null ) return undefined!
|
|
43
|
-
|
|
44
|
-
if ( param instanceof Persistent ) return param.toObject()
|
|
45
|
-
|
|
46
|
-
if ( Array.isArray( param ) ) {
|
|
47
|
-
return param.map( p => this.processParam( p ) ) as unknown as P
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
if ( typeof param === 'object' ) {
|
|
51
|
-
return Object.entries( param ).reduce(( newParam, [ key, value ])=>{
|
|
52
|
-
newParam[ key ] = this.processParam( value )
|
|
53
|
-
return newParam
|
|
54
|
-
}, {}) as P
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
return param
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
private processResult<R>( value: R | PersistentObject<R & Persistent> ): R {
|
|
61
|
-
if ( value === undefined || value === null ) return undefined!
|
|
62
|
-
|
|
63
|
-
if ( ( value as PersistentObject<R & Persistent> ).__className ) {
|
|
64
|
-
return Persistent.createInstance( value as PersistentObject<R & Persistent> ) as R
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
if ( Array.isArray( value ) ) {
|
|
68
|
-
return value.map( elem => this.processResult( elem ) ) as unknown as R
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
if ( typeof value === 'object' ) {
|
|
72
|
-
return Object.entries( value ).reduce((newVal, [ key, val ]) => {
|
|
73
|
-
newVal[ key ] = this.processResult( val )
|
|
74
|
-
return newVal
|
|
75
|
-
}, {}) as R
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
return value as R
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
private static _cloudFunctionsService: CloudFunctionsService
|
|
82
|
-
private static _instance: CloudFunctions
|
|
83
|
-
}
|
|
@@ -1,207 +0,0 @@
|
|
|
1
|
-
import { Persistent, persistent, registerPersistentClass } from '../persistent/persistent'
|
|
2
|
-
import { JsonDataSource } from '../store/json-data-source'
|
|
3
|
-
import { Model } from '../store/model'
|
|
4
|
-
import { Store } from '../store/store'
|
|
5
|
-
import { CloudStorage } from './cloud-storage'
|
|
6
|
-
import { MockCloudStorage } from './mock-cloud-storage'
|
|
7
|
-
import { StoredFile, StoredFileEvent } from './stored-file'
|
|
8
|
-
|
|
9
|
-
function MockFile(this: any, data: any[], filename: string ) {
|
|
10
|
-
this.data = data as any[]
|
|
11
|
-
this.name = filename
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
global.File = MockFile as any
|
|
15
|
-
|
|
16
|
-
@registerPersistentClass( 'Test' )
|
|
17
|
-
class Test extends Persistent {
|
|
18
|
-
|
|
19
|
-
get file(): StoredFile {
|
|
20
|
-
return this._file
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
@persistent private _file: StoredFile = new StoredFile()
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
describe( 'Cloud Storage', ()=>{
|
|
27
|
-
let testObj: Test
|
|
28
|
-
let file: StoredFile
|
|
29
|
-
const blobData1 = new Uint8Array([0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x2c, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x21]);
|
|
30
|
-
const blobData2 = new Uint8Array([0x6c, 0x6c, 0x6f, 0x2c, 0x48, 0x65, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x21]);
|
|
31
|
-
const fileData = new MockFile( [blobData1], 'pepe.dat' )
|
|
32
|
-
|
|
33
|
-
const mockCloudStorage = new MockCloudStorage( 'mock-data-folder/' )
|
|
34
|
-
|
|
35
|
-
beforeEach(()=>{
|
|
36
|
-
CloudStorage.useCloudStorage( mockCloudStorage )
|
|
37
|
-
testObj = new Test()
|
|
38
|
-
file = new StoredFile()
|
|
39
|
-
})
|
|
40
|
-
|
|
41
|
-
afterEach( ()=> mockCloudStorage.mockFileSystem = {} )
|
|
42
|
-
|
|
43
|
-
it( 'should save a file from Blob', async ()=>{
|
|
44
|
-
await file.save({ data: blobData1 })
|
|
45
|
-
expect( mockCloudStorage.mockFileSystem[ file.id ] ).toBeDefined()
|
|
46
|
-
expect( mockCloudStorage.mockFileSystem[ file.id ] ).toEqual( JSON.stringify( blobData1 ) )
|
|
47
|
-
})
|
|
48
|
-
|
|
49
|
-
it( 'should save a file from File', async ()=>{
|
|
50
|
-
await file.save({ data: fileData })
|
|
51
|
-
expect( mockCloudStorage.mockFileSystem[ file.id ] ).toBeDefined()
|
|
52
|
-
expect( mockCloudStorage.mockFileSystem[ file.id ] ).toEqual( JSON.stringify( {data:[blobData1], name: 'pepe.dat'} ) )
|
|
53
|
-
expect( file.originalFileName ).toEqual( 'pepe.dat' )
|
|
54
|
-
expect( file.url ).toEqual( 'mock-data-folder/pepe.dat' )
|
|
55
|
-
})
|
|
56
|
-
|
|
57
|
-
it( 'should get a url', async ()=>{
|
|
58
|
-
await file.save({ data: blobData1 })
|
|
59
|
-
|
|
60
|
-
expect( file.url ).toEqual( 'mock-data-folder/' + file.id )
|
|
61
|
-
})
|
|
62
|
-
|
|
63
|
-
it( 'should report metadata', async ()=>{
|
|
64
|
-
await file.save({ data: blobData1, fileName: 'test.dat' })
|
|
65
|
-
|
|
66
|
-
expect( file.originalFileName ).toEqual( 'test.dat' )
|
|
67
|
-
expect( file.provider.className ).toEqual( 'MockCloudStorage' )
|
|
68
|
-
})
|
|
69
|
-
|
|
70
|
-
it( 'should delete file', async ()=>{
|
|
71
|
-
await file.save({ data: blobData1 })
|
|
72
|
-
expect( mockCloudStorage.mockFileSystem[ file.id ] ).toBeDefined()
|
|
73
|
-
|
|
74
|
-
await file.delete()
|
|
75
|
-
expect( file.url ).toBeUndefined()
|
|
76
|
-
expect( mockCloudStorage.mockFileSystem[ file.id ] ).not.toBeDefined()
|
|
77
|
-
})
|
|
78
|
-
|
|
79
|
-
it( 'should throw if not stored file', async ()=>{
|
|
80
|
-
let thrown = false
|
|
81
|
-
|
|
82
|
-
try{
|
|
83
|
-
await file.delete()
|
|
84
|
-
}
|
|
85
|
-
catch {
|
|
86
|
-
thrown = true
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
expect( thrown ).toBeTruthy()
|
|
90
|
-
})
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
it( 'should overwrite file on subsequent writes', async ()=>{
|
|
94
|
-
const deleteSpy = vi.spyOn( file, 'delete' )
|
|
95
|
-
|
|
96
|
-
await file.save({ data: 'first write' as any })
|
|
97
|
-
expect( deleteSpy ).not.toHaveBeenCalled()
|
|
98
|
-
expect( mockCloudStorage.mockFileSystem[ file.id ] ).toEqual( '"first write"' )
|
|
99
|
-
|
|
100
|
-
await file.save({ data: 'second write' as any })
|
|
101
|
-
expect( deleteSpy ).toHaveBeenCalled()
|
|
102
|
-
expect( mockCloudStorage.mockFileSystem[ file.id ] ).toEqual( '"second write"' )
|
|
103
|
-
})
|
|
104
|
-
|
|
105
|
-
it( 'should save from pending file', async ()=>{
|
|
106
|
-
file.setDataToStore( fileData )
|
|
107
|
-
await file.save()
|
|
108
|
-
|
|
109
|
-
expect( mockCloudStorage.mockFileSystem[ file.id ] ).toBeDefined()
|
|
110
|
-
expect( mockCloudStorage.mockFileSystem[ file.id ] ).toEqual( JSON.stringify( {data:[blobData1], name: 'pepe.dat'} ) )
|
|
111
|
-
})
|
|
112
|
-
|
|
113
|
-
describe( 'Notify on change', ()=>{
|
|
114
|
-
let spy: vi.Mock
|
|
115
|
-
|
|
116
|
-
beforeEach(()=>{
|
|
117
|
-
spy = vi.fn()
|
|
118
|
-
file.onChange( spy )
|
|
119
|
-
})
|
|
120
|
-
|
|
121
|
-
afterEach( ()=> spy.mockClear() )
|
|
122
|
-
|
|
123
|
-
it( 'should notify on seting pendind data to store', ()=>{
|
|
124
|
-
file.setDataToStore( fileData )
|
|
125
|
-
expect( spy ).toHaveBeenNthCalledWith( 1, {
|
|
126
|
-
event: StoredFileEvent.pendingDataSet,
|
|
127
|
-
pendingData: fileData,
|
|
128
|
-
storedFile: file
|
|
129
|
-
})
|
|
130
|
-
})
|
|
131
|
-
|
|
132
|
-
it( 'should notify on data store', async ()=>{
|
|
133
|
-
await file.save( fileData )
|
|
134
|
-
expect( spy ).toHaveBeenNthCalledWith( 1, {
|
|
135
|
-
event: StoredFileEvent.stored,
|
|
136
|
-
storedFile: file
|
|
137
|
-
})
|
|
138
|
-
})
|
|
139
|
-
|
|
140
|
-
it( 'should notify on delete', async ()=>{
|
|
141
|
-
await file.save( fileData )
|
|
142
|
-
spy.mockClear()
|
|
143
|
-
|
|
144
|
-
await file.delete()
|
|
145
|
-
expect( spy ).toHaveBeenNthCalledWith( 1, {
|
|
146
|
-
event: StoredFileEvent.deleted,
|
|
147
|
-
storedFile: file
|
|
148
|
-
})
|
|
149
|
-
})
|
|
150
|
-
})
|
|
151
|
-
|
|
152
|
-
describe( 'Streaming', ()=>{
|
|
153
|
-
const database = {}
|
|
154
|
-
let model: Model<Test>
|
|
155
|
-
let testObj: Test
|
|
156
|
-
|
|
157
|
-
beforeEach(()=>{
|
|
158
|
-
Store.useDataSource( new JsonDataSource( database ) )
|
|
159
|
-
testObj = new Test()
|
|
160
|
-
model = Store.getModel<Test>( testObj )
|
|
161
|
-
})
|
|
162
|
-
|
|
163
|
-
it( 'should save object with StoredFile', async ()=>{
|
|
164
|
-
await testObj.file.save({ data: blobData1, fileName: 'test.dat' })
|
|
165
|
-
await model.save( testObj )
|
|
166
|
-
|
|
167
|
-
expect( database[ testObj.className ][ testObj.id ].file ).toBeDefined()
|
|
168
|
-
expect( database[ testObj.className ][ testObj.id ].file.reference ).toEqual( testObj.file.id )
|
|
169
|
-
expect( database[ testObj.className ][ testObj.id ].file.url ).toEqual( 'mock-data-folder/' + testObj.file.id )
|
|
170
|
-
expect( database[ testObj.className ][ testObj.id ].file.cloudStorageProviderName ).toEqual( 'MockCloudStorage' )
|
|
171
|
-
expect( database[ testObj.className ][ testObj.id ].file.originalFileName ).toEqual( 'test.dat' )
|
|
172
|
-
})
|
|
173
|
-
|
|
174
|
-
it( 'should load object with StoredFile', async ()=>{
|
|
175
|
-
await testObj.file.save({ data: blobData1, fileName: 'test.dat' })
|
|
176
|
-
await model.save( testObj )
|
|
177
|
-
|
|
178
|
-
const newTestObj = await model.findById( testObj.id )
|
|
179
|
-
|
|
180
|
-
expect( newTestObj?.file ).toBeInstanceOf( StoredFile )
|
|
181
|
-
expect( newTestObj?.file.url ).toEqual( 'mock-data-folder/' + testObj.file.id )
|
|
182
|
-
})
|
|
183
|
-
|
|
184
|
-
it( 'should replace file on save after load', async ()=>{
|
|
185
|
-
const deleteSpy = vi.spyOn( testObj.file, 'delete' )
|
|
186
|
-
|
|
187
|
-
await testObj.file.save({ data: blobData1, fileName: 'test.dat' })
|
|
188
|
-
await model.save( testObj )
|
|
189
|
-
|
|
190
|
-
const newTestObj = await model.findById( testObj.id )
|
|
191
|
-
|
|
192
|
-
expect( newTestObj?.file ).toBeInstanceOf( StoredFile )
|
|
193
|
-
expect( newTestObj?.file.url ).toEqual( 'mock-data-folder/' + testObj.file.id )
|
|
194
|
-
expect( deleteSpy ).not.toHaveBeenCalled()
|
|
195
|
-
|
|
196
|
-
testObj.file.setDataToStore( blobData2 )
|
|
197
|
-
await testObj.file.save()
|
|
198
|
-
|
|
199
|
-
expect(
|
|
200
|
-
mockCloudStorage.mockFileSystem[ testObj.file.id ]
|
|
201
|
-
).toEqual( JSON.stringify( blobData2 ) )
|
|
202
|
-
|
|
203
|
-
expect( deleteSpy ).toHaveBeenCalled()
|
|
204
|
-
})
|
|
205
|
-
|
|
206
|
-
})
|
|
207
|
-
})
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
export type UploadProgress = ( uploadedBytes: number, fileSize: number ) => void
|
|
2
|
-
|
|
3
|
-
type CloudStorageFactory = ()=>CloudStorage
|
|
4
|
-
|
|
5
|
-
interface CloudStorageFactoryMap {
|
|
6
|
-
[ cloudStorageProviderName: string ] : CloudStorageFactory
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export interface UploadControl {
|
|
10
|
-
pause: ()=>void
|
|
11
|
-
resume: ()=>void
|
|
12
|
-
cancel: ()=>void
|
|
13
|
-
onProgress: ( callback: UploadProgress )=>void
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export type StorableData = File | Blob | Uint8Array | ArrayBuffer
|
|
17
|
-
|
|
18
|
-
export abstract class CloudStorage {
|
|
19
|
-
abstract save( id: string, data: StorableData, progress?: UploadProgress ): Promise<string>
|
|
20
|
-
abstract getUrl( reference: string ): Promise<string>
|
|
21
|
-
abstract uploadControl(): UploadControl
|
|
22
|
-
abstract delete( reference: string ): Promise<void>
|
|
23
|
-
|
|
24
|
-
static registerCloudStorage( cloudStorageProviderName: string, factory: CloudStorageFactory ) {
|
|
25
|
-
CloudStorage._cloudStorageFactoryMap[ cloudStorageProviderName ] = factory
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
static createInstance( providerName: string ) {
|
|
29
|
-
const provider = CloudStorage._cloudStorageFactoryMap[ providerName ]
|
|
30
|
-
if ( !provider ) {
|
|
31
|
-
throw new Error( `You should register the ${ providerName } cloud storage provider prior to use it`)
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
return provider()
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
get className(): string {
|
|
38
|
-
return this[ '__className' ];
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
static useCloudStorage( provider: CloudStorage ) {
|
|
42
|
-
CloudStorage._defaultCloudStorage = provider
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
static get defaultCloudStorage() {
|
|
46
|
-
if ( !CloudStorage._defaultCloudStorage ) {
|
|
47
|
-
throw new Error( 'You should define a default cloud storage provider prior to use it')
|
|
48
|
-
}
|
|
49
|
-
return CloudStorage._defaultCloudStorage
|
|
50
|
-
}
|
|
51
|
-
static _defaultCloudStorage: CloudStorage
|
|
52
|
-
private static _cloudStorageFactoryMap: CloudStorageFactoryMap = {}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
export function registerCloudStorage( cloudStorageProviderName: string, factory: CloudStorageFactory ) {
|
|
56
|
-
CloudStorage.registerCloudStorage( cloudStorageProviderName, factory )
|
|
57
|
-
return ( constructor: Function ) => {
|
|
58
|
-
constructor.prototype.__className = cloudStorageProviderName
|
|
59
|
-
}
|
|
60
|
-
}
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
import { CloudStorage, registerCloudStorage, StorableData, UploadControl, UploadProgress } from './cloud-storage'
|
|
2
|
-
|
|
3
|
-
@registerCloudStorage( 'MockCloudStorage', ()=>new MockCloudStorage() )
|
|
4
|
-
export class MockCloudStorage extends CloudStorage {
|
|
5
|
-
constructor( pathToMockFiles: string = '' ) {
|
|
6
|
-
super()
|
|
7
|
-
this._pathToMockFiles = pathToMockFiles
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Introduce a delay in the execution of operations to simulate a real data source
|
|
12
|
-
* @param miliSeconds the number of milliseconds to delay the execution of operations
|
|
13
|
-
* @returns a chainable reference to this object
|
|
14
|
-
*/
|
|
15
|
-
simulateDelay( miliSeconds: number ) {
|
|
16
|
-
this._simulateDelay = miliSeconds
|
|
17
|
-
return this
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
private resolveWithDelay<T>( data?: T ): Promise<T> {
|
|
21
|
-
if ( this._simulateDelay <= 0 ) return Promise.resolve( data! )
|
|
22
|
-
|
|
23
|
-
const promise = new Promise<T>( resolve => {
|
|
24
|
-
setTimeout(
|
|
25
|
-
()=> resolve( data! ),
|
|
26
|
-
this._simulateDelay
|
|
27
|
-
)
|
|
28
|
-
})
|
|
29
|
-
this._pendingPromises.push( promise )
|
|
30
|
-
promise.finally(
|
|
31
|
-
()=> this._pendingPromises = this._pendingPromises.filter( p => p === promise )
|
|
32
|
-
)
|
|
33
|
-
return promise
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
save( id: string, data: StorableData ): Promise<string> {
|
|
37
|
-
const fullPath = id
|
|
38
|
-
|
|
39
|
-
if ( this._onProgress ) this._onProgress( 0, 100 )
|
|
40
|
-
|
|
41
|
-
this.mockFileSystem[ id ] = JSON.stringify( data )
|
|
42
|
-
|
|
43
|
-
if ( this._onProgress ) this._onProgress( 100, 100 )
|
|
44
|
-
|
|
45
|
-
const ref = data instanceof File? data.name : fullPath
|
|
46
|
-
return this.resolveWithDelay( ref )
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
uploadControl(): UploadControl {
|
|
50
|
-
return {
|
|
51
|
-
resume: ()=>{},
|
|
52
|
-
pause: ()=>{},
|
|
53
|
-
cancel: ()=>{},
|
|
54
|
-
onProgress: callback => this._onProgress = callback
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
getUrl( reference: string ): Promise<string> {
|
|
59
|
-
return Promise.resolve( this._pathToMockFiles + reference )
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
delete( reference: string ) {
|
|
63
|
-
delete this.mockFileSystem[ reference ]
|
|
64
|
-
return this.resolveWithDelay<void>()
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
private _simulateDelay: number = 0
|
|
68
|
-
private _pendingPromises: Promise<any>[] = []
|
|
69
|
-
private _onProgress: UploadProgress | undefined
|
|
70
|
-
private _pathToMockFiles: string
|
|
71
|
-
public mockFileSystem = {}
|
|
72
|
-
}
|
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
import { Callback, Observable } from '../observable/observable'
|
|
2
|
-
import { persistent, Persistent, registerPersistentClass } from '../persistent/persistent'
|
|
3
|
-
import { CloudStorage, StorableData, UploadControl, UploadProgress } from './cloud-storage'
|
|
4
|
-
|
|
5
|
-
export enum StoredFileEvent { stored, pendingDataSet, deleted }
|
|
6
|
-
export interface StoredFileChange {
|
|
7
|
-
event: StoredFileEvent
|
|
8
|
-
pendingData?: StorableData
|
|
9
|
-
storedFile: StoredFile
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export interface StoreParams {
|
|
13
|
-
data?: StorableData,
|
|
14
|
-
fileName?: string,
|
|
15
|
-
progress?: UploadProgress,
|
|
16
|
-
cloudStorageProvider?: CloudStorage
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
@registerPersistentClass( 'StoredFile' )
|
|
20
|
-
export class StoredFile extends Persistent{
|
|
21
|
-
|
|
22
|
-
async save({ data, fileName, progress, cloudStorageProvider }: StoreParams = {}): Promise<void> {
|
|
23
|
-
const dataToStore = data || this._pendingData
|
|
24
|
-
if ( !dataToStore ) return
|
|
25
|
-
if ( this._reference ) await this.delete()
|
|
26
|
-
|
|
27
|
-
this.provider = cloudStorageProvider || CloudStorage.defaultCloudStorage
|
|
28
|
-
this._originalFileName = fileName || ( dataToStore instanceof File? dataToStore.name : undefined )
|
|
29
|
-
|
|
30
|
-
this._reference = await this.provider.save( this.id, dataToStore, progress )
|
|
31
|
-
this._url = await this.provider.getUrl( this._reference )
|
|
32
|
-
|
|
33
|
-
this._pendingData = undefined
|
|
34
|
-
this._onChange.notify({ event: StoredFileEvent.stored, storedFile: this })
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
uploadControl(): UploadControl {
|
|
38
|
-
return this.provider.uploadControl()
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
async delete(): Promise<void> {
|
|
42
|
-
if ( !this._reference ) throw new Error( 'Cannot delete a not stored file' )
|
|
43
|
-
await this.provider.delete( this._reference )
|
|
44
|
-
this._reference = undefined
|
|
45
|
-
this._url = undefined
|
|
46
|
-
this._onChange.notify({ event: StoredFileEvent.deleted, storedFile: this })
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
set provider( value: CloudStorage ) {
|
|
50
|
-
this._provider = value
|
|
51
|
-
this._cloudStorageProviderName = value.className
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
get provider() {
|
|
55
|
-
if ( !this._provider ) {
|
|
56
|
-
try {
|
|
57
|
-
this._provider = CloudStorage.createInstance( this._cloudStorageProviderName! )
|
|
58
|
-
}
|
|
59
|
-
catch {
|
|
60
|
-
this._provider = CloudStorage.defaultCloudStorage
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
return this._provider
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
get url() {
|
|
67
|
-
return this._url
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
get mimeType() {
|
|
71
|
-
return this._mimeType
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
setDataToStore( data: StorableData ) {
|
|
75
|
-
this._pendingData = data
|
|
76
|
-
this._originalFileName = data instanceof File? data.name : undefined
|
|
77
|
-
this._mimeType = data instanceof Blob? data.type : undefined
|
|
78
|
-
this._onChange.notify({
|
|
79
|
-
event: StoredFileEvent.pendingDataSet,
|
|
80
|
-
pendingData: data,
|
|
81
|
-
storedFile: this
|
|
82
|
-
})
|
|
83
|
-
return this
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
get originalFileName() {
|
|
87
|
-
return this._originalFileName
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
onChange( listenerCallback: Callback<StoredFileChange> ) {
|
|
91
|
-
return this._onChange.subscribe( listenerCallback )
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
@persistent private _reference: string | undefined
|
|
95
|
-
@persistent private _url: string | undefined
|
|
96
|
-
@persistent private _cloudStorageProviderName: string | undefined
|
|
97
|
-
@persistent private _originalFileName: string | undefined
|
|
98
|
-
@persistent private _mimeType: string | undefined
|
|
99
|
-
private _provider: CloudStorage | undefined
|
|
100
|
-
private _pendingData: StorableData | undefined
|
|
101
|
-
private _onChange: Observable<StoredFileChange> = new Observable<StoredFileChange>()
|
|
102
|
-
}
|
package/src/index.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
export * from './observable/observable'
|
|
2
|
-
export * from './persistent/entropic-component'
|
|
3
|
-
export * from './persistent/persistent'
|
|
4
|
-
export * from './store/data-source'
|
|
5
|
-
export * from './store/json-data-source'
|
|
6
|
-
export * from './store/store'
|
|
7
|
-
export * from './store/model'
|
|
8
|
-
export * from './types/utility-types'
|
|
9
|
-
export * from './cloud-storage/cloud-storage'
|
|
10
|
-
export * from './cloud-storage/mock-cloud-storage'
|
|
11
|
-
export * from './cloud-storage/stored-file'
|
|
12
|
-
export * from './auth/auth'
|
|
13
|
-
export * from './auth/user-auth-types'
|
|
14
|
-
export * from './auth/auth-mock'
|
|
15
|
-
export * from './cloud-functions/cloud-functions'
|
|
16
|
-
export * from './cloud-functions/cloud-functions-mock'
|
|
17
|
-
export * from './server-auth/server-auth'
|
|
18
|
-
export * from './server-auth/server-auth-mock'
|
|
19
|
-
export * from './utils/utils'
|
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
import {Observable} from './observable'
|
|
2
|
-
|
|
3
|
-
class ObserverTest {
|
|
4
|
-
public changed: boolean = true
|
|
5
|
-
userChanged() {
|
|
6
|
-
this.changed = true
|
|
7
|
-
}
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
interface MockEvent {
|
|
11
|
-
[ idx: string ]: any
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
describe('observer', () => {
|
|
15
|
-
let observable: Observable<MockEvent | void>
|
|
16
|
-
|
|
17
|
-
beforeEach(()=>{
|
|
18
|
-
observable = new Observable<MockEvent | void>()
|
|
19
|
-
})
|
|
20
|
-
|
|
21
|
-
it('should subscribe ', () => {
|
|
22
|
-
const mockObserver = new ObserverTest();
|
|
23
|
-
const changedSpy = vi.spyOn( mockObserver, 'userChanged' )
|
|
24
|
-
|
|
25
|
-
observable.subscribe( ()=>mockObserver.userChanged() )
|
|
26
|
-
observable.notify()
|
|
27
|
-
|
|
28
|
-
expect( changedSpy ).toBeCalledTimes(1)
|
|
29
|
-
})
|
|
30
|
-
|
|
31
|
-
it('should notify', ()=>{
|
|
32
|
-
const myCallback = vi.fn()
|
|
33
|
-
|
|
34
|
-
observable.subscribe( myCallback )
|
|
35
|
-
observable.notify()
|
|
36
|
-
|
|
37
|
-
expect( myCallback ).toHaveBeenCalledTimes(1)
|
|
38
|
-
})
|
|
39
|
-
|
|
40
|
-
it('should notify all subscribers', () => {
|
|
41
|
-
const callbackOne = vi.fn()
|
|
42
|
-
const callbackTwo = vi.fn()
|
|
43
|
-
const callbackThree = vi.fn()
|
|
44
|
-
observable.subscribe(callbackOne)
|
|
45
|
-
observable.subscribe(callbackTwo)
|
|
46
|
-
observable.subscribe(callbackThree)
|
|
47
|
-
|
|
48
|
-
observable.notify()
|
|
49
|
-
|
|
50
|
-
expect(callbackOne).toHaveBeenCalledTimes(1)
|
|
51
|
-
expect(callbackTwo).toHaveBeenCalledTimes(1)
|
|
52
|
-
expect(callbackThree).toHaveBeenCalledTimes(1)
|
|
53
|
-
})
|
|
54
|
-
|
|
55
|
-
it( 'should notify with event', ()=>{
|
|
56
|
-
const myCallback = vi.fn()
|
|
57
|
-
const obj: MockEvent = {name: 'Juan'};
|
|
58
|
-
|
|
59
|
-
observable.subscribe( myCallback )
|
|
60
|
-
observable.notify(obj)
|
|
61
|
-
|
|
62
|
-
expect( myCallback ).toHaveBeenCalledWith( obj )
|
|
63
|
-
})
|
|
64
|
-
|
|
65
|
-
it('should not notify removed listeners', ()=>{
|
|
66
|
-
const callbackOne = vi.fn()
|
|
67
|
-
const callbackTwo = vi.fn()
|
|
68
|
-
const callbackThree = vi.fn()
|
|
69
|
-
observable.subscribe(callbackOne)
|
|
70
|
-
observable.subscribe(callbackTwo)
|
|
71
|
-
observable.subscribe(callbackThree)
|
|
72
|
-
|
|
73
|
-
observable.notify()
|
|
74
|
-
|
|
75
|
-
expect(callbackOne).toHaveBeenCalledTimes(1)
|
|
76
|
-
expect(callbackTwo).toHaveBeenCalledTimes(1)
|
|
77
|
-
expect(callbackThree).toHaveBeenCalledTimes(1)
|
|
78
|
-
|
|
79
|
-
observable.unsubscribe( callbackThree )
|
|
80
|
-
|
|
81
|
-
observable.notify()
|
|
82
|
-
|
|
83
|
-
expect(callbackOne).toHaveBeenCalledTimes(2)
|
|
84
|
-
expect(callbackTwo).toHaveBeenCalledTimes(2)
|
|
85
|
-
expect(callbackThree).toHaveBeenCalledTimes(1)
|
|
86
|
-
})
|
|
87
|
-
|
|
88
|
-
it( 'should return an unsubscribe function on subscribe', ()=>{
|
|
89
|
-
const cb = vi.fn()
|
|
90
|
-
const unsubscriber = observable.subscribe( cb )
|
|
91
|
-
unsubscriber()
|
|
92
|
-
|
|
93
|
-
observable.notify()
|
|
94
|
-
expect( cb ).not.toHaveBeenCalled()
|
|
95
|
-
})
|
|
96
|
-
|
|
97
|
-
it( 'should return the number of subscribers', ()=>{
|
|
98
|
-
const cb = vi.fn()
|
|
99
|
-
observable.subscribe( cb )
|
|
100
|
-
observable.subscribe( cb )
|
|
101
|
-
observable.subscribe( vi.fn() )
|
|
102
|
-
|
|
103
|
-
expect( observable.subscribersCount ).toBe( 2 )
|
|
104
|
-
})
|
|
105
|
-
})
|