@neuralinnovations/dataisland-sdk 0.0.1-dev1

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/types.ts ADDED
@@ -0,0 +1,110 @@
1
+ import { type Events, type Event } from './events'
2
+ import { type Disposable } from './disposable'
3
+
4
+ export interface Collection<T> {
5
+ get collection(): T[]
6
+ }
7
+
8
+ export type OrganizationId = string
9
+ export type WorkspaceId = string
10
+ export type ChatId = string
11
+ export type FileId = string
12
+
13
+ export enum OrganizationEvent {
14
+ ADDED,
15
+ REMOVED,
16
+ UPDATED
17
+ }
18
+
19
+ export enum FileEvent {
20
+ ADDED,
21
+ REMOVED,
22
+ UPDATED
23
+ }
24
+
25
+ export enum ChatEvent {
26
+ ADDED,
27
+ REMOVED,
28
+ UPDATED
29
+ }
30
+
31
+ export enum ChatMessageEvent {
32
+ ADDED,
33
+ REMOVED,
34
+ UPDATED
35
+ }
36
+
37
+ export interface File {
38
+ id: FileId
39
+ name: string
40
+
41
+ download: () => Promise<void>
42
+ }
43
+
44
+ export interface Files {
45
+ files: File[]
46
+ on: (callback: (event: Event<FileEvent, File>) => void) => Disposable
47
+ fetch: () => Promise<void>
48
+ upload: (path: string, name: string) => Promise<File>
49
+ }
50
+
51
+ // eslint-disable-next-line @typescript-eslint/no-empty-interface
52
+ export interface ChatMessage {}
53
+
54
+ export interface Chat {
55
+ id: ChatId
56
+ name: string
57
+ on: (
58
+ callback: (event: Event<ChatMessageEvent, ChatMessage>) => void
59
+ ) => Disposable
60
+ messages: ChatMessage[]
61
+ fetch: () => Promise<void>
62
+ subscribe: () => void
63
+ unsubscribe: () => void
64
+ }
65
+
66
+ export interface Chats {
67
+ chats: Chat[]
68
+ newChat: (name: string) => Promise<Chat>
69
+ on: (callback: (event: Event<ChatEvent, Chat>) => void) => Disposable
70
+ fetch: () => Promise<void>
71
+ }
72
+
73
+ export interface Invites {
74
+ invite: (email: string) => Promise<void>
75
+ accept: (id: OrganizationId) => Promise<void>
76
+ decline: (id: OrganizationId) => Promise<void>
77
+ on: (
78
+ callback: (organization: Event<OrganizationEvent, Organization>) => void
79
+ ) => Disposable
80
+ }
81
+
82
+ // eslint-disable-next-line @typescript-eslint/no-empty-interface
83
+ export interface Statistics {}
84
+
85
+ export interface Organization {
86
+ name: string
87
+ description: string
88
+ id: OrganizationId
89
+ chats: Chats
90
+ files: Files
91
+ invites: Invites
92
+ statistics: Statistics
93
+ workspaces: Workspaces
94
+ }
95
+
96
+ // eslint-disable-next-line @typescript-eslint/no-empty-interface
97
+ export interface Workspace {}
98
+
99
+ export interface Workspaces {
100
+ newWorkspace: (name: string) => Promise<Workspace>
101
+
102
+ delete: (id: WorkspaceId) => Promise<void>
103
+ }
104
+
105
+ export interface Organizations
106
+ extends Events<OrganizationEvent, Organization>,
107
+ Collection<Organization> {
108
+ create: (name: string) => Promise<Organization>
109
+ delete: (id: OrganizationId) => Promise<void>
110
+ }
@@ -0,0 +1,39 @@
1
+ import { DisposableContainer } from '../src'
2
+
3
+ test('DisposableContainer', () => {
4
+ const disposable = new DisposableContainer()
5
+ expect(disposable.isDisposed).toBe(false)
6
+ expect(disposable.lifetime.isDisposed).toBe(false)
7
+ disposable.dispose()
8
+ expect(disposable.isDisposed).toBe(true)
9
+ expect(disposable.lifetime.isDisposed).toBe(true)
10
+ })
11
+
12
+ test('DisposableContainer, dispose order', () => {
13
+ const indexes: number[] = []
14
+ const disposable = new DisposableContainer()
15
+ disposable.addCallback(() => {
16
+ indexes.push(1)
17
+ })
18
+
19
+ const nested = disposable.defineNested()
20
+ nested.addCallback(() => {
21
+ indexes.push(2)
22
+ })
23
+
24
+ nested.lifetime.addCallback(() => {
25
+ indexes.push(3)
26
+ })
27
+
28
+ nested.lifetime.defineNested().addCallback(() => {
29
+ indexes.push(4)
30
+ })
31
+
32
+ nested.lifetime.defineNested().addCallback(() => {
33
+ indexes.push(5)
34
+ })
35
+
36
+ disposable.dispose()
37
+
38
+ expect(indexes).toEqual([5, 4, 3, 2, 1])
39
+ })
@@ -0,0 +1,151 @@
1
+ import { EventDispatcher } from '../src'
2
+
3
+ test('Events, test general', () => {
4
+ enum ET {
5
+ A,
6
+ B
7
+ }
8
+
9
+ const dispatch = new EventDispatcher<ET, number>()
10
+
11
+ let a1 = 0
12
+ let a2 = 0
13
+ let b1 = 0
14
+ let b2 = 0
15
+
16
+ const aDisposable1 = dispatch.subscribe((evt: { data: number }) => {
17
+ a1 += evt.data
18
+ }, ET.A)
19
+ const aDisposable2 = dispatch.subscribe(evt => {
20
+ if (evt.type === ET.A) a2 += evt.data
21
+ })
22
+ const bDisposable1 = dispatch.subscribe(evt => {
23
+ b1 += evt.data
24
+ }, ET.B)
25
+ const bDisposable2 = dispatch.subscribe(evt => {
26
+ if (evt.type === ET.B) b2 += evt.data
27
+ })
28
+
29
+ dispatch.dispatch({
30
+ type: ET.A,
31
+ data: 1
32
+ })
33
+
34
+ expect(a1).toBe(1)
35
+ expect(a2).toBe(1)
36
+ expect(b1).toBe(0)
37
+ expect(b2).toBe(0)
38
+
39
+ aDisposable1.dispose()
40
+
41
+ dispatch.dispatch({
42
+ type: ET.A,
43
+ data: 2
44
+ })
45
+ dispatch.dispatch({
46
+ type: ET.B,
47
+ data: 3
48
+ })
49
+
50
+ expect(a1).toBe(1)
51
+ expect(a2).toBe(3)
52
+ expect(b1).toBe(3)
53
+ expect(b2).toBe(3)
54
+
55
+ aDisposable2.dispose()
56
+
57
+ dispatch.dispatch({
58
+ type: ET.A,
59
+ data: 3
60
+ })
61
+
62
+ expect(a1).toBe(1)
63
+ expect(a2).toBe(3)
64
+ expect(b1).toBe(3)
65
+ expect(b2).toBe(3)
66
+
67
+ bDisposable1.dispose()
68
+ bDisposable2.dispose()
69
+
70
+ dispatch.dispatch({
71
+ type: ET.B,
72
+ data: 4
73
+ })
74
+
75
+ expect(a1).toBe(1)
76
+ expect(a2).toBe(3)
77
+ expect(b1).toBe(3)
78
+ expect(b2).toBe(3)
79
+ })
80
+
81
+ test('Events, test this', () => {
82
+ enum ET {
83
+ A,
84
+ B
85
+ }
86
+
87
+ const dispatch = new EventDispatcher<ET, number>()
88
+
89
+ const a = {
90
+ value: 0
91
+ }
92
+ const b = {
93
+ value: 0
94
+ }
95
+
96
+ const aDisposable = dispatch.subscribe((evt: { data: number }) => {
97
+ a.value += evt.data
98
+ }, ET.A)
99
+ const bDisposable = dispatch.subscribe((evt: { data: number }) => {
100
+ b.value += evt.data
101
+ }, ET.B)
102
+
103
+ dispatch.dispatch({
104
+ type: ET.A,
105
+ data: 1
106
+ })
107
+ dispatch.dispatch({
108
+ type: ET.B,
109
+ data: 2
110
+ })
111
+
112
+ expect(a.value).toBe(1)
113
+ expect(b.value).toBe(2)
114
+
115
+ aDisposable.dispose()
116
+ bDisposable.dispose()
117
+
118
+ dispatch.dispatch({
119
+ type: ET.A,
120
+ data: 3
121
+ })
122
+ dispatch.dispatch({
123
+ type: ET.B,
124
+ data: 4
125
+ })
126
+
127
+ expect(a.value).toBe(1)
128
+ expect(b.value).toBe(2)
129
+ })
130
+
131
+ test('Events, test unsubscribe', () => {
132
+ const dispatch = new EventDispatcher<unknown, number>()
133
+
134
+ let index = 0
135
+
136
+ dispatch.subscribe(evt => {
137
+ index += evt.data
138
+ evt.unsubscribe()
139
+ })
140
+ dispatch.subscribe(evt => {
141
+ index += evt.data
142
+ })
143
+
144
+ dispatch.dispatch({ data: 1 })
145
+
146
+ expect(index).toBe(2)
147
+
148
+ dispatch.dispatch({ data: 1 })
149
+
150
+ expect(index).toBe(3)
151
+ })
@@ -0,0 +1,83 @@
1
+ import { version } from '../package.json'
2
+ import {
3
+ BasicCredential,
4
+ appSdk,
5
+ SDK_VERSION,
6
+ DEFAULT_NAME,
7
+ DEFAULT_HOST
8
+ } from '../src'
9
+ import { MiddlewareService } from '../src/services/middlewareService'
10
+ import { CredentialService } from '../src/services/credentialService'
11
+ import { RpcService, RpcServiceImpl } from '../src/services/rpcService'
12
+ import { AppBuilder } from '../src/appBuilder'
13
+
14
+ test('SDK_VERSION', () => {
15
+ expect(SDK_VERSION).toBe(version)
16
+ })
17
+
18
+ test('Default SDK', async () => {
19
+ // default
20
+ const app = await appSdk()
21
+ expect(app.name).toBe(DEFAULT_NAME)
22
+ expect(app.host).toBe(DEFAULT_HOST)
23
+ expect(app.automaticDataCollectionEnabled).toBe(true)
24
+ })
25
+
26
+ test('Custom SDK settings', async () => {
27
+ const app = await appSdk('test', async (builder: AppBuilder) => {
28
+ builder.useHost('https://test.com')
29
+ builder.useAutomaticDataCollectionEnabled(false)
30
+ builder.useCredential(new BasicCredential('email', 'password'))
31
+ builder.addMiddleware(async (req, next) => {
32
+ req.headers.set('X-Test', 'test')
33
+ await next(req)
34
+ })
35
+ })
36
+ expect(app.name).toBe('test')
37
+ expect(app.host).toBe('https://test.com')
38
+ expect(app.automaticDataCollectionEnabled).toBe(false)
39
+ })
40
+
41
+ test('SDK, services', async () => {
42
+ const app = await appSdk('test')
43
+ const middlewareService = app.resolve(MiddlewareService)
44
+ expect(middlewareService).not.toBeUndefined()
45
+ expect(app.resolve(MiddlewareService)).toBe(middlewareService)
46
+ expect(app.resolve(CredentialService)).not.toBeUndefined()
47
+ expect(app.resolve(RpcService)).not.toBeUndefined()
48
+ expect(app.resolve(RpcService)).toBeInstanceOf(RpcServiceImpl)
49
+ })
50
+
51
+ test('SDK, middleware', async () => {
52
+ const app = await appSdk('test')
53
+ const middlewareService = app.resolve(MiddlewareService)
54
+ expect(middlewareService).not.toBeUndefined()
55
+ expect(app.resolve(MiddlewareService)).toBe(middlewareService)
56
+ expect(app.resolve(CredentialService)).not.toBeUndefined()
57
+
58
+ const response = await middlewareService?.process(
59
+ new Request('http://localhost:8080'),
60
+ async (req: Request): Promise<Response> => {
61
+ const headerXTest = req.headers.get('Custom-Test-Header')
62
+ expect(headerXTest).toBeNull()
63
+ return new Response('', { status: 200 })
64
+ }
65
+ )
66
+ expect(response).not.toBeUndefined()
67
+ expect(response?.status).toBe(200)
68
+
69
+ middlewareService?.useMiddleware(async (req, next) => {
70
+ req.headers.set('X-Test', 'test-value')
71
+ await next(req)
72
+ })
73
+
74
+ const response2 = await middlewareService?.process(
75
+ new Request('https://localhost:8080'),
76
+ async (req: Request): Promise<Response> => {
77
+ expect(req.headers.get('X-Test')).toBe('test-value')
78
+ return new Response('', { status: 400 })
79
+ }
80
+ )
81
+ expect(response2).not.toBeUndefined()
82
+ expect(response2?.status).toBe(400)
83
+ })
@@ -0,0 +1,44 @@
1
+ import { Registry } from '../src/internal/registry'
2
+
3
+ class TestClass {
4
+ constructor(public readonly value: string) {}
5
+ }
6
+
7
+ test('Registry, test factory', () => {
8
+ const registry = new Registry()
9
+
10
+ const item = new TestClass('test1')
11
+ registry.map(TestClass).asValue(item)
12
+ expect(registry.get(TestClass)).toBe(item)
13
+
14
+ let index = 0
15
+
16
+ registry.map(TestClass).asFactory(() => {
17
+ index++
18
+ return new TestClass(`test_${index}`)
19
+ })
20
+
21
+ expect(registry.get(TestClass)).toBeInstanceOf(TestClass)
22
+ expect(registry.get(TestClass)).not.toBe(item)
23
+ expect(registry.get(TestClass)).not.toBe(registry.get(TestClass))
24
+
25
+ expect(registry.get(TestClass)?.value).toBe('test_5')
26
+ })
27
+
28
+ test('Registry, test value', () => {
29
+ const registry = new Registry()
30
+
31
+ const item = new TestClass('test1')
32
+ registry.map(TestClass).asValue(item)
33
+ expect(registry.get(TestClass)).toBeInstanceOf(TestClass)
34
+ expect(registry.get(TestClass)).toBe(item)
35
+ })
36
+
37
+ test('Registry, test singleton', () => {
38
+ const registry = new Registry()
39
+
40
+ registry.map(TestClass).asSingleton(() => new TestClass('test1'))
41
+ const singleton = registry.get(TestClass)
42
+ expect(singleton).toBeInstanceOf(TestClass)
43
+ expect(singleton).toBe(registry.get(TestClass))
44
+ })
package/tsconfig.json ADDED
@@ -0,0 +1,31 @@
1
+ {
2
+ "compileOnSave": false,
3
+ "compilerOptions": {
4
+ "target": "ES2015",
5
+ "module": "amd",
6
+ "moduleResolution": "node",
7
+ "typeRoots": [
8
+ "node_modules/@types"
9
+ ],
10
+ "resolveJsonModule": true,
11
+ "declaration": true,
12
+ "sourceMap": true,
13
+ "importHelpers": true,
14
+ "esModuleInterop": true,
15
+ "forceConsistentCasingInFileNames": true,
16
+ "strict": true,
17
+ "skipLibCheck": true,
18
+ "outDir": "dist",
19
+ "outFile": "dist/dataisland-sdk.js",
20
+ "rootDir": ".",
21
+ "allowJs": true,
22
+ "checkJs": true,
23
+ "downlevelIteration": true
24
+ },
25
+ "exclude": [
26
+ "dist/**/*"
27
+ ],
28
+ "include": [
29
+ "src/**/*"
30
+ ]
31
+ }