@streamlayer/sdk-web-core 0.0.1

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/README.md ADDED
@@ -0,0 +1,6 @@
1
+ # core
2
+
3
+ This library was generated with [Nx](https://nx.dev).
4
+
5
+ ## Building
6
+ Run `nx build core` to build the library.
@@ -0,0 +1,49 @@
1
+ import { AbstractAuthenticationProvider } from '@streamlayer/sdk-web-interfaces';
2
+ import { Transport } from '@streamlayer/sdk-web-api';
3
+ import { CoreStore } from '../../store/store';
4
+ /**
5
+ * An authorization service manages user access by providing login, logout,
6
+ * authentication checks, and the ability to revoke access.
7
+ * Subscribed to $userStore and automatically updates the auth header for the Transport.
8
+ */
9
+ export declare class BypassAuth extends AbstractAuthenticationProvider {
10
+ private readonly $coreStore;
11
+ private readonly transport;
12
+ private readonly bypassLogin;
13
+ constructor(store: CoreStore, transport: Transport);
14
+ me: () => Promise<import("@streamlayer/sl-eslib/users/users_common_pb").User | undefined>;
15
+ /**
16
+ * Login user by token and schema.
17
+ * On success, save the user and update the token to the Transport, UserStore and cache.
18
+ * @param schema - schema created by the host app and provided to the StreamLayer SDK.
19
+ * @param userKey - user token received from the host app.
20
+ */
21
+ login: (schema: string, userKey: string) => Promise<string>;
22
+ isAuthenticated: () => Promise<import("@streamlayer/sl-eslib/users/users_common_pb").User | undefined>;
23
+ /**
24
+ * Logout user. Clears the all user data from the store.
25
+ */
26
+ logout: () => void;
27
+ /**
28
+ * Soft logout, only clears the StreamLayer user data from the store.
29
+ * Does not clear the external token. And automatically tries to re-login by external token.
30
+ */
31
+ softLogout: () => void;
32
+ /**
33
+ * Try to re-login.
34
+ * - If the user has an token, then try to login by it, by calling the me() method.
35
+ * - If the user has an external token, then try to login by it, by calling the login() method. On failure, logout.
36
+ * -
37
+ * - If no one of the above is true, then logout.
38
+ */
39
+ reLogin: () => Promise<void> | undefined;
40
+ /**
41
+ * Write token to the Transport and UserStore
42
+ */
43
+ private saveUser;
44
+ /**
45
+ * Add interceptor to the Transport to handle 401 and 403 errors.
46
+ * If the user is logged in (auth header is set), then make a soft logout.
47
+ */
48
+ private connect;
49
+ }
@@ -0,0 +1,132 @@
1
+ import { AbstractAuthenticationProvider } from '@streamlayer/sdk-web-interfaces';
2
+ import { queries } from '@streamlayer/sdk-web-api';
3
+ import { UserStorage } from '../../storage';
4
+ /**
5
+ * An authorization service manages user access by providing login, logout,
6
+ * authentication checks, and the ability to revoke access.
7
+ * Subscribed to $userStore and automatically updates the auth header for the Transport.
8
+ */
9
+ export class BypassAuth extends AbstractAuthenticationProvider {
10
+ $coreStore;
11
+ transport;
12
+ bypassLogin;
13
+ constructor(store, transport) {
14
+ super();
15
+ this.$coreStore = store;
16
+ this.transport = transport;
17
+ this.bypassLogin = queries.bypassLogin(this.transport);
18
+ this.connect();
19
+ }
20
+ me = async () => {
21
+ this.$coreStore.getValues().user.invalidate();
22
+ const res = await this.$coreStore.getValues().user.getValue();
23
+ return res?.data;
24
+ };
25
+ /**
26
+ * Login user by token and schema.
27
+ * On success, save the user and update the token to the Transport, UserStore and cache.
28
+ * @param schema - schema created by the host app and provided to the StreamLayer SDK.
29
+ * @param userKey - user token received from the host app.
30
+ */
31
+ login = async (schema, userKey) => {
32
+ this.$coreStore.getValues().userKey.setValue(userKey);
33
+ const user = await this.bypassLogin({ schema, userKey, init: false });
34
+ const token = user.meta?.jwt;
35
+ const userId = user.data?.id;
36
+ if (!token || !userId) {
37
+ throw new Error('internal: token missing');
38
+ }
39
+ this.$coreStore.getValues().user.getStore().mutate(user);
40
+ this.saveUser(token, userId);
41
+ return token;
42
+ };
43
+ isAuthenticated = () => {
44
+ return this.me();
45
+ };
46
+ /**
47
+ * Logout user. Clears the all user data from the store.
48
+ */
49
+ logout = () => {
50
+ this.$coreStore.getValues().user.setValue();
51
+ this.$coreStore.getValues().userKey.setValue();
52
+ this.$coreStore.getValues().userToken.setValue();
53
+ this.transport.setAuth('', '');
54
+ const storage = new UserStorage();
55
+ storage.clear();
56
+ };
57
+ /**
58
+ * Soft logout, only clears the StreamLayer user data from the store.
59
+ * Does not clear the external token. And automatically tries to re-login by external token.
60
+ */
61
+ softLogout = () => {
62
+ const storage = new UserStorage();
63
+ this.$coreStore.getValues().user.setValue();
64
+ this.$coreStore.getValues().userToken.setValue();
65
+ this.transport.setAuth('', '');
66
+ storage.setToken('');
67
+ void this.reLogin();
68
+ };
69
+ /**
70
+ * Try to re-login.
71
+ * - If the user has an token, then try to login by it, by calling the me() method.
72
+ * - If the user has an external token, then try to login by it, by calling the login() method. On failure, logout.
73
+ * -
74
+ * - If no one of the above is true, then logout.
75
+ */
76
+ reLogin = () => {
77
+ const storage = new UserStorage();
78
+ const prevUserToken = storage.getToken();
79
+ const prevUserExternalToken = storage.getExternalToken();
80
+ this.$coreStore.getValues().userKey.setValue(prevUserExternalToken);
81
+ this.$coreStore.getValues().userToken.setValue(prevUserToken);
82
+ if (prevUserToken) {
83
+ this.saveUser(prevUserToken, '');
84
+ return this.me().then((user) => {
85
+ console.log('user', user);
86
+ if (user?.id) {
87
+ const userId = user.id;
88
+ this.saveUser(prevUserToken, userId);
89
+ }
90
+ });
91
+ }
92
+ if (prevUserExternalToken && !prevUserToken) {
93
+ const prevUserSchema = storage.getSchema();
94
+ if (prevUserSchema && prevUserExternalToken) {
95
+ this.login(prevUserSchema, prevUserExternalToken).catch(() => {
96
+ this.logout();
97
+ });
98
+ }
99
+ }
100
+ return undefined;
101
+ };
102
+ /**
103
+ * Write token to the Transport and UserStore
104
+ */
105
+ saveUser = (token, userId) => {
106
+ this.transport.setAuth(token, userId);
107
+ this.$coreStore.getValues().userToken.setValue(token);
108
+ const storage = new UserStorage();
109
+ storage.setToken(token);
110
+ };
111
+ /**
112
+ * Add interceptor to the Transport to handle 401 and 403 errors.
113
+ * If the user is logged in (auth header is set), then make a soft logout.
114
+ */
115
+ connect = () => {
116
+ this.transport.registerInterceptor((next) => async (req) => {
117
+ try {
118
+ return await next(req);
119
+ }
120
+ catch (err) {
121
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
122
+ // @ts-ignore
123
+ if (err.code && (err.code === 7 || err.code === 16)) {
124
+ if (this.transport.getHeader('authorization')) {
125
+ this.softLogout();
126
+ }
127
+ }
128
+ throw err;
129
+ }
130
+ });
131
+ };
132
+ }
@@ -0,0 +1,22 @@
1
+ import { StreamLayerContext } from '@streamlayer/sdk-web-interfaces';
2
+ import { CoreStores, StoreObj } from '../store/store';
3
+ import { UserStorage } from '../storage';
4
+ import { BypassAuth } from './bypass';
5
+ declare module '@streamlayer/sdk-web-interfaces' {
6
+ interface StreamLayerSDK {
7
+ authorizationBypass: (schema: string, userKey: string) => Promise<void>;
8
+ logout: () => void;
9
+ getUserStore: () => CoreStores['user'];
10
+ userId: StoreObj['user']['getAtomStore'];
11
+ isUserAuthorized: BypassAuth['isAuthenticated'];
12
+ }
13
+ interface StreamLayerContext {
14
+ auth: BypassAuth;
15
+ }
16
+ }
17
+ export declare const storage: UserStorage;
18
+ /**
19
+ * Bypass authorization, used for login with external token.
20
+ * Automatically login user if SDK initialized and READY.
21
+ */
22
+ export declare const bypass: (instance: StreamLayerContext, opts: unknown, done: () => void) => void;
@@ -0,0 +1,43 @@
1
+ import { CoreStatus } from '../store/store';
2
+ import { UserStorage } from '../storage';
3
+ import { BypassAuth } from './bypass';
4
+ export const storage = new UserStorage();
5
+ /**
6
+ * Bypass authorization, used for login with external token.
7
+ * Automatically login user if SDK initialized and READY.
8
+ */
9
+ export const bypass = (instance, opts, done) => {
10
+ instance.auth = new BypassAuth(instance.store, instance.transport);
11
+ instance.stores.status.listen((status) => {
12
+ if (status === CoreStatus.READY) {
13
+ void instance.auth.reLogin();
14
+ }
15
+ });
16
+ instance.sdk.userId = instance.stores.user.getAtomStore;
17
+ instance.sdk.authorizationBypass = async (schema, userKey) => {
18
+ if (storage.getSchema() === schema &&
19
+ storage.getExternalToken() === userKey &&
20
+ instance.transport.getHeader('authorization')) {
21
+ return;
22
+ }
23
+ try {
24
+ await instance.auth.login(schema, userKey);
25
+ storage.setSchema(schema);
26
+ storage.setExternalToken(userKey);
27
+ }
28
+ catch (err) {
29
+ instance.sdk.logout();
30
+ }
31
+ };
32
+ instance.sdk.logout = () => {
33
+ instance.auth.logout();
34
+ storage.clear();
35
+ };
36
+ instance.sdk.getUserStore = () => {
37
+ return instance.stores.user.getStore();
38
+ };
39
+ instance.sdk.isUserAuthorized = () => {
40
+ return instance.auth.isAuthenticated();
41
+ };
42
+ done();
43
+ };
@@ -0,0 +1,3 @@
1
+ export declare const environment: {
2
+ production: boolean;
3
+ };
@@ -0,0 +1,5 @@
1
+ // This file can be replaced during build by using the `fileReplacements` array.
2
+ // When building for production, this file is replaced with `environment.prod.ts`.
3
+ export const environment = {
4
+ production: false,
5
+ };
@@ -0,0 +1,3 @@
1
+ export declare const environment: {
2
+ production: boolean;
3
+ };
@@ -0,0 +1,3 @@
1
+ export const environment = {
2
+ production: true,
3
+ };
package/lib/index.d.ts ADDED
@@ -0,0 +1,26 @@
1
+ import { StreamLayerContext } from '@streamlayer/sdk-web-interfaces';
2
+ export { bypass, storage } from './auth';
3
+ export { store } from './store';
4
+ import './store';
5
+ import './auth';
6
+ declare module '@streamlayer/sdk-web-interfaces' {
7
+ interface StreamLayerSDK {
8
+ initializeApp: () => Promise<{
9
+ enabled?: boolean;
10
+ err?: string;
11
+ }>;
12
+ disableApp: () => void;
13
+ createEventSession: (providerStreamId: string) => void;
14
+ }
15
+ }
16
+ /**
17
+ * The main application instance is the core of a application. It includes:
18
+ * Store: Manages data storage.
19
+ * Public Methods: Provides a way to interact with the application.
20
+ * Connect Features: Handles communication between components through store.
21
+ * Connect Transport: Handles communication with api.
22
+ * Dependency Injection: Incorporates other necessary instances.
23
+ * Error Handling: Manages errors and logs them.
24
+ * Security: Implements authentication and authorization.
25
+ */
26
+ export declare const core: (instance: StreamLayerContext, opts: unknown, done: () => void) => void;
package/lib/index.js ADDED
@@ -0,0 +1,61 @@
1
+ import { CoreStatus } from './store/store';
2
+ export { bypass, storage } from './auth';
3
+ export { store } from './store';
4
+ import './store';
5
+ import './auth';
6
+ /**
7
+ * The main application instance is the core of a application. It includes:
8
+ * Store: Manages data storage.
9
+ * Public Methods: Provides a way to interact with the application.
10
+ * Connect Features: Handles communication between components through store.
11
+ * Connect Transport: Handles communication with api.
12
+ * Dependency Injection: Incorporates other necessary instances.
13
+ * Error Handling: Manages errors and logs them.
14
+ * Security: Implements authentication and authorization.
15
+ */
16
+ export const core = (instance, opts, done) => {
17
+ instance.sdk = Object.create(null);
18
+ /**
19
+ * On initialize we subscribe to store and launch listeners
20
+ * that activate data downloading over the network
21
+ */
22
+ instance.sdk.initializeApp = async () => {
23
+ if (instance.stores.enabled.get() === 'on') {
24
+ return { enabled: true };
25
+ }
26
+ instance.storeSubscribe();
27
+ instance.stores.enabled.setValue('on');
28
+ instance.stores.status.setValue(CoreStatus.INITIALIZATION);
29
+ try {
30
+ const organizationSettings = await instance.stores.organizationSettings.getValue();
31
+ if (organizationSettings) {
32
+ instance.stores.status.setValue(CoreStatus.READY);
33
+ return { enabled: !!organizationSettings };
34
+ }
35
+ instance.stores.status.setValue(CoreStatus.FAILED);
36
+ return { err: 'failed' };
37
+ }
38
+ catch (err) {
39
+ instance.stores.enabled.setValue();
40
+ instance.stores.status.setValue(CoreStatus.FAILED);
41
+ return { err: `${err}` };
42
+ }
43
+ };
44
+ instance.sdk.disableApp = () => {
45
+ if (instance.stores.enabled.get() !== 'on') {
46
+ return;
47
+ }
48
+ instance.stores.enabled.setValue();
49
+ instance.stores.status.setValue(CoreStatus.DISABLED);
50
+ instance.sdk.closeFeature();
51
+ instance.storeUnsubscribe();
52
+ };
53
+ /**
54
+ * Configure the "event id" using the "provider," enabling subscribed stores to
55
+ * trigger their logic in response to a new event.
56
+ */
57
+ instance.sdk.createEventSession = (providerStreamId) => {
58
+ instance.stores.providerStreamId.setValue(providerStreamId);
59
+ };
60
+ done();
61
+ };
@@ -0,0 +1,11 @@
1
+ import { Storage } from '@streamlayer/sdk-web-storage';
2
+ export declare class UserStorage extends Storage {
3
+ constructor();
4
+ setSchema: (value: string) => void;
5
+ getSchema: () => string | undefined;
6
+ setToken: (value: string) => void;
7
+ getToken: () => string | undefined;
8
+ setExternalToken: (value: string) => void;
9
+ getExternalToken: () => string | undefined;
10
+ removeToken: () => void;
11
+ }
package/lib/storage.js ADDED
@@ -0,0 +1,36 @@
1
+ import { Storage } from '@streamlayer/sdk-web-storage';
2
+ var KEY_PREFIX;
3
+ (function (KEY_PREFIX) {
4
+ KEY_PREFIX["SCHEMA"] = "schema";
5
+ KEY_PREFIX["EXTERNAL_TOKEN"] = "eToken";
6
+ KEY_PREFIX["TOKEN"] = "token";
7
+ })(KEY_PREFIX || (KEY_PREFIX = {}));
8
+ export class UserStorage extends Storage {
9
+ constructor() {
10
+ super('user');
11
+ }
12
+ // Schema
13
+ setSchema = (value) => {
14
+ this.write(KEY_PREFIX.SCHEMA, value);
15
+ };
16
+ getSchema = () => {
17
+ return this.read(KEY_PREFIX.SCHEMA);
18
+ };
19
+ // Token
20
+ setToken = (value) => {
21
+ this.write(KEY_PREFIX.TOKEN, value);
22
+ };
23
+ getToken = () => {
24
+ return this.read(KEY_PREFIX.TOKEN);
25
+ };
26
+ // External Token
27
+ setExternalToken = (value) => {
28
+ this.write(KEY_PREFIX.EXTERNAL_TOKEN, value);
29
+ };
30
+ getExternalToken = () => {
31
+ return this.read(KEY_PREFIX.EXTERNAL_TOKEN);
32
+ };
33
+ removeToken = () => {
34
+ this.remove(KEY_PREFIX.TOKEN);
35
+ };
36
+ }
@@ -0,0 +1,21 @@
1
+ import { StreamLayerContext } from '@streamlayer/sdk-web-interfaces';
2
+ import { CoreStore, CoreStores, StoreObj } from './store';
3
+ declare module '@streamlayer/sdk-web-interfaces' {
4
+ interface StreamLayerSDK {
5
+ sdkStore: CoreStores;
6
+ enabled: CoreStores['enabled'];
7
+ status: CoreStores['status'];
8
+ organizationStore: () => CoreStores['organizationSettings'];
9
+ streamStore: () => CoreStores['streamSettings'];
10
+ }
11
+ interface StreamLayerContext {
12
+ store: CoreStore;
13
+ stores: StoreObj;
14
+ storeSubscribe: () => void;
15
+ storeUnsubscribe: () => void;
16
+ }
17
+ }
18
+ /**
19
+ * store plugin, connect store to sdk
20
+ */
21
+ export declare const store: (instance: StreamLayerContext, opts: unknown, done: () => void) => void;
@@ -0,0 +1,17 @@
1
+ import { CoreStore } from './store';
2
+ /**
3
+ * store plugin, connect store to sdk
4
+ */
5
+ export const store = (instance, opts, done) => {
6
+ instance.store = new CoreStore(instance.transport);
7
+ instance.stores = instance.store.getValues();
8
+ instance.sdk.enabled = instance.stores.enabled.getStore();
9
+ instance.sdk.status = instance.stores.status.getStore();
10
+ instance.sdk.sdkStore = Object.fromEntries(Object.entries(instance.stores).map(([key, store]) => [key, store.getStore()]));
11
+ instance.sdk.organizationStore = () => instance.stores.organizationSettings.getStore();
12
+ instance.sdk.streamStore = () => instance.stores.streamSettings.getStore();
13
+ instance.storeUnsubscribe = () => {
14
+ instance.store.unsubscribe();
15
+ };
16
+ done();
17
+ };
@@ -0,0 +1,54 @@
1
+ import { SingleStore, ApiStore } from '@streamlayer/sdk-web-interfaces';
2
+ import { Transport } from '@streamlayer/sdk-web-api';
3
+ export declare enum CoreStatus {
4
+ DISABLED = "disabled",
5
+ INITIALIZATION = "initialization",
6
+ READY = "ready",
7
+ FAILED = "failed",
8
+ SUSPENDED = "suspended"
9
+ }
10
+ export declare const initializeStore: (transport: Transport) => {
11
+ readonly enabled: SingleStore<unknown, import("nanostores").WritableAtom<"on" | undefined>>;
12
+ readonly status: SingleStore<unknown, import("nanostores").WritableAtom<CoreStatus>>;
13
+ readonly providerStreamId: SingleStore<unknown, import("nanostores").WritableAtom<string | undefined>>;
14
+ readonly slStreamId: ApiStore<string | undefined, import("@nanostores/query").FetcherStore<string | undefined, any>>;
15
+ readonly streamSettings: ApiStore<import("@streamlayer/sl-eslib/sdkSettings/sdkSettings.common_pb").StreamSettings | undefined, import("@nanostores/query").FetcherStore<import("@streamlayer/sl-eslib/sdkSettings/sdkSettings.common_pb").StreamSettings | undefined, any>>;
16
+ readonly user: ApiStore<import("@streamlayer/sl-eslib/users/users_pb").MeResponse | undefined, import("@nanostores/query").FetcherStore<import("@streamlayer/sl-eslib/users/users_pb").MeResponse | undefined, any>>;
17
+ readonly userKey: SingleStore<unknown, import("nanostores").WritableAtom<string | undefined>>;
18
+ readonly userToken: SingleStore<unknown, import("nanostores").WritableAtom<string | undefined>>;
19
+ readonly userSettings: ApiStore<import("@streamlayer/sl-eslib/sdkSettings/client/client_pb").ClientSettings | undefined, import("@nanostores/query").FetcherStore<import("@streamlayer/sl-eslib/sdkSettings/client/client_pb").ClientSettings | undefined, any>>;
20
+ readonly organizationSettings: ApiStore<{
21
+ id: string;
22
+ overlays?: import("@streamlayer/sl-eslib/sdkSettings/sdkSettings.common_pb").SdkOverlay[] | undefined;
23
+ buttonIcon?: string | undefined;
24
+ tinodeHost?: string | undefined;
25
+ audience?: string | undefined;
26
+ name?: string | undefined;
27
+ provider?: string | undefined;
28
+ primaryColor?: string | undefined;
29
+ secondaryColor?: string | undefined;
30
+ moderationPrimaryColor?: string | undefined;
31
+ linkShareIcon?: string | undefined;
32
+ linkShareText?: string | undefined;
33
+ brandDefaults?: import("@streamlayer/sl-eslib/sdkSettings/sdkSettings.common_pb").BrandDefaults | undefined;
34
+ pub?: import("@streamlayer/sl-eslib/sdkSettings/sdkSettings.common_pb").JWK | undefined;
35
+ getstream?: import("@streamlayer/sl-eslib/sdkSettings/sdkSettings.common_pb").GetStreamSettingsClient | undefined;
36
+ } | undefined, import("@nanostores/query").FetcherStore<{
37
+ id: string;
38
+ overlays?: import("@streamlayer/sl-eslib/sdkSettings/sdkSettings.common_pb").SdkOverlay[] | undefined;
39
+ buttonIcon?: string | undefined;
40
+ tinodeHost?: string | undefined;
41
+ audience?: string | undefined;
42
+ name?: string | undefined;
43
+ provider?: string | undefined;
44
+ primaryColor?: string | undefined;
45
+ secondaryColor?: string | undefined;
46
+ moderationPrimaryColor?: string | undefined;
47
+ linkShareIcon?: string | undefined;
48
+ linkShareText?: string | undefined;
49
+ brandDefaults?: import("@streamlayer/sl-eslib/sdkSettings/sdkSettings.common_pb").BrandDefaults | undefined;
50
+ pub?: import("@streamlayer/sl-eslib/sdkSettings/sdkSettings.common_pb").JWK | undefined;
51
+ getstream?: import("@streamlayer/sl-eslib/sdkSettings/sdkSettings.common_pb").GetStreamSettingsClient | undefined;
52
+ } | undefined, any>>;
53
+ readonly organizationAdvertising: ApiStore<import("@streamlayer/sl-eslib/sdkSettings/sdkSettings.common_pb").Advertising | undefined, import("@nanostores/query").FetcherStore<import("@streamlayer/sl-eslib/sdkSettings/sdkSettings.common_pb").Advertising | undefined, any>>;
54
+ };
@@ -0,0 +1,71 @@
1
+ import { createSingleStore, SingleStore, ApiStore } from '@streamlayer/sdk-web-interfaces';
2
+ import { queries } from '@streamlayer/sdk-web-api';
3
+ import { UserStorage } from '../storage';
4
+ export var CoreStatus;
5
+ (function (CoreStatus) {
6
+ CoreStatus["DISABLED"] = "disabled";
7
+ CoreStatus["INITIALIZATION"] = "initialization";
8
+ CoreStatus["READY"] = "ready";
9
+ CoreStatus["FAILED"] = "failed";
10
+ CoreStatus["SUSPENDED"] = "suspended";
11
+ })(CoreStatus || (CoreStatus = {}));
12
+ const initializeUserStores = (transport) => {
13
+ const storage = new UserStorage();
14
+ // host user key
15
+ const userKey = new SingleStore(createSingleStore(storage.getExternalToken()), 'userKey');
16
+ // sl user key
17
+ const userToken = new SingleStore(createSingleStore(storage.getToken()), 'userToken');
18
+ // sl user data
19
+ const user = new ApiStore(queries.$user(userToken.getStore(), transport), 'user', (data) => data?.data?.data?.id);
20
+ // sl user settings
21
+ const userSettings = new ApiStore(queries.$userSettings(userToken.getStore(), transport), 'userSettings');
22
+ return {
23
+ userKey,
24
+ userToken,
25
+ user,
26
+ userSettings,
27
+ };
28
+ };
29
+ const initializeStreamStores = (transport) => {
30
+ // host event id
31
+ const providerStreamId = new SingleStore(createSingleStore(undefined), 'providerStreamId');
32
+ // sl event id
33
+ const slStreamId = new ApiStore(queries.$retrieveEventId(providerStreamId.getStore(), transport), 'slStreamId', (data) => data?.data);
34
+ // sl stream settings
35
+ const streamSettings = new ApiStore(queries.$streamSettings(slStreamId.getAtomStore(), transport), 'streamSettings');
36
+ slStreamId.getAtomStore().listen((eventId) => {
37
+ if (eventId === '' || eventId === undefined) {
38
+ streamSettings.getStore().mutate(undefined);
39
+ }
40
+ });
41
+ return {
42
+ providerStreamId,
43
+ slStreamId,
44
+ streamSettings,
45
+ };
46
+ };
47
+ export const initializeStore = (transport) => {
48
+ // sdk toggle
49
+ const enabled = new SingleStore(createSingleStore(undefined), 'enabled');
50
+ // sdk status
51
+ const status = new SingleStore(createSingleStore(CoreStatus.DISABLED), 'status');
52
+ // sl organization settings
53
+ const organizationSettings = new ApiStore(queries.$organizationSettings(enabled.getStore(), transport), 'organizationSettings', (data) => data?.data?.id);
54
+ // sl organization advertising
55
+ const organizationAdvertising = new ApiStore(queries.$organizationAdvertising(organizationSettings.getAtomStore(), transport), 'organizationAdvertising');
56
+ const userStores = initializeUserStores(transport);
57
+ const streamStores = initializeStreamStores(transport);
58
+ return {
59
+ enabled,
60
+ status,
61
+ providerStreamId: streamStores.providerStreamId,
62
+ slStreamId: streamStores.slStreamId,
63
+ streamSettings: streamStores.streamSettings,
64
+ user: userStores.user,
65
+ userKey: userStores.userKey,
66
+ userToken: userStores.userToken,
67
+ userSettings: userStores.userSettings,
68
+ organizationSettings,
69
+ organizationAdvertising,
70
+ };
71
+ };
@@ -0,0 +1,101 @@
1
+ import type { OrganizationAdvertising, StreamSettings, OrganizationSettings, User, UserSettings } from '@streamlayer/sdk-web-types';
2
+ import { AbstractStore } from '@streamlayer/sdk-web-interfaces';
3
+ import { Transport } from '@streamlayer/sdk-web-api';
4
+ import { ReadableAtom } from 'nanostores';
5
+ import { FetcherValue } from '@nanostores/query';
6
+ import { initializeStore, CoreStatus } from './init';
7
+ export { CoreStatus };
8
+ export interface CoreStoreInterface {
9
+ enabled?: 'on';
10
+ status: string;
11
+ userKey?: string;
12
+ userToken?: string;
13
+ organizationSettings?: OrganizationSettings & {
14
+ id: string;
15
+ };
16
+ organizationAdvertising?: OrganizationAdvertising;
17
+ streamSettings?: StreamSettings;
18
+ user?: User;
19
+ userSettings?: UserSettings;
20
+ providerStreamId?: string;
21
+ slStreamId?: string;
22
+ }
23
+ export type StoreObj = ReturnType<typeof initializeStore>;
24
+ export type CoreStores = {
25
+ [Index in keyof StoreObj]: ReturnType<StoreObj[Index]['getStore']>;
26
+ };
27
+ export type CoreStoresValues = {
28
+ [Index in keyof StoreObj]: ReturnType<StoreObj[Index]['getStore']>['value'];
29
+ };
30
+ export type CoreStoreInstance = ReadableAtom<CoreStoresValues>;
31
+ /**
32
+ * @description `CoreStore` is a store that contains all the necessary data for the SDK to work.
33
+ * `CoreStore` is a singleton and is created when the SDK is initialized. It includes the following stores:
34
+ * - `enabled` - the status of the SDK. The SDK is enabled when the `on` value is set.
35
+ * - `status` - the status of the SDK. Can be one of the following values: `disabled`, `initialization`, `ready`, `failed`, `suspended`.
36
+ * - `userKey` - the user key provided by the host.
37
+ * - `userToken` - the user token received from the StreamLayer after login.
38
+ * - `organizationSettings` - the organization settings.
39
+ * - `organizationAdvertising` - the organization advertising.
40
+ * - `streamSettings` - the stream settings.
41
+ * - `user` - the user data.
42
+ * - `userSettings` - the user settings.
43
+ * - `providerStreamId` - the event id provided by the host.
44
+ * - `slStreamId` - the event id received from the StreamLayer, resolved by the `providerStreamId`.
45
+ */
46
+ export declare class CoreStore extends AbstractStore<CoreStoreInstance> {
47
+ private stores;
48
+ constructor(transport: Transport);
49
+ getValue(): unknown;
50
+ getValues(): {
51
+ readonly enabled: import("@streamlayer/sdk-web-interfaces").SingleStore<unknown, import("nanostores").WritableAtom<"on" | undefined>>;
52
+ readonly status: import("@streamlayer/sdk-web-interfaces").SingleStore<unknown, import("nanostores").WritableAtom<CoreStatus>>;
53
+ readonly providerStreamId: import("@streamlayer/sdk-web-interfaces").SingleStore<unknown, import("nanostores").WritableAtom<string | undefined>>;
54
+ readonly slStreamId: import("@streamlayer/sdk-web-interfaces").ApiStore<string | undefined, import("@nanostores/query").FetcherStore<string | undefined, any>>;
55
+ readonly streamSettings: import("@streamlayer/sdk-web-interfaces").ApiStore<import("@streamlayer/sl-eslib/sdkSettings/sdkSettings.common_pb").StreamSettings | undefined, import("@nanostores/query").FetcherStore<import("@streamlayer/sl-eslib/sdkSettings/sdkSettings.common_pb").StreamSettings | undefined, any>>;
56
+ readonly user: import("@streamlayer/sdk-web-interfaces").ApiStore<import("@streamlayer/sl-eslib/users/users_pb").MeResponse | undefined, import("@nanostores/query").FetcherStore<import("@streamlayer/sl-eslib/users/users_pb").MeResponse | undefined, any>>;
57
+ readonly userKey: import("@streamlayer/sdk-web-interfaces").SingleStore<unknown, import("nanostores").WritableAtom<string | undefined>>;
58
+ readonly userToken: import("@streamlayer/sdk-web-interfaces").SingleStore<unknown, import("nanostores").WritableAtom<string | undefined>>;
59
+ readonly userSettings: import("@streamlayer/sdk-web-interfaces").ApiStore<import("@streamlayer/sl-eslib/sdkSettings/client/client_pb").ClientSettings | undefined, import("@nanostores/query").FetcherStore<import("@streamlayer/sl-eslib/sdkSettings/client/client_pb").ClientSettings | undefined, any>>;
60
+ readonly organizationSettings: import("@streamlayer/sdk-web-interfaces").ApiStore<{
61
+ id: string;
62
+ overlays?: import("@streamlayer/sl-eslib/sdkSettings/sdkSettings.common_pb").SdkOverlay[] | undefined;
63
+ buttonIcon?: string | undefined;
64
+ tinodeHost?: string | undefined;
65
+ audience?: string | undefined;
66
+ name?: string | undefined;
67
+ provider?: string | undefined;
68
+ primaryColor?: string | undefined;
69
+ secondaryColor?: string | undefined;
70
+ moderationPrimaryColor?: string | undefined;
71
+ linkShareIcon?: string | undefined;
72
+ linkShareText?: string | undefined;
73
+ brandDefaults?: import("@streamlayer/sl-eslib/sdkSettings/sdkSettings.common_pb").BrandDefaults | undefined;
74
+ pub?: import("@streamlayer/sl-eslib/sdkSettings/sdkSettings.common_pb").JWK | undefined;
75
+ getstream?: import("@streamlayer/sl-eslib/sdkSettings/sdkSettings.common_pb").GetStreamSettingsClient | undefined;
76
+ } | undefined, import("@nanostores/query").FetcherStore<{
77
+ id: string;
78
+ overlays?: import("@streamlayer/sl-eslib/sdkSettings/sdkSettings.common_pb").SdkOverlay[] | undefined;
79
+ buttonIcon?: string | undefined;
80
+ tinodeHost?: string | undefined;
81
+ audience?: string | undefined;
82
+ name?: string | undefined;
83
+ provider?: string | undefined;
84
+ primaryColor?: string | undefined;
85
+ secondaryColor?: string | undefined;
86
+ moderationPrimaryColor?: string | undefined;
87
+ linkShareIcon?: string | undefined;
88
+ linkShareText?: string | undefined;
89
+ brandDefaults?: import("@streamlayer/sl-eslib/sdkSettings/sdkSettings.common_pb").BrandDefaults | undefined;
90
+ pub?: import("@streamlayer/sl-eslib/sdkSettings/sdkSettings.common_pb").JWK | undefined;
91
+ getstream?: import("@streamlayer/sl-eslib/sdkSettings/sdkSettings.common_pb").GetStreamSettingsClient | undefined;
92
+ } | undefined, any>>;
93
+ readonly organizationAdvertising: import("@streamlayer/sdk-web-interfaces").ApiStore<import("@streamlayer/sl-eslib/sdkSettings/sdkSettings.common_pb").Advertising | undefined, import("@nanostores/query").FetcherStore<import("@streamlayer/sl-eslib/sdkSettings/sdkSettings.common_pb").Advertising | undefined, any>>;
94
+ };
95
+ setValue(): void;
96
+ subscribe: (subscribes: Partial<StoreListeners>) => void;
97
+ unsubscribe: () => void;
98
+ }
99
+ export type StoreListeners = {
100
+ [Index in keyof StoreObj]: (params: FetcherValue<CoreStoreInterface[Index]>) => void;
101
+ };
@@ -0,0 +1,51 @@
1
+ import { AbstractStore, mergeStores } from '@streamlayer/sdk-web-interfaces';
2
+ import { initializeStore, CoreStatus } from './init';
3
+ export { CoreStatus };
4
+ /**
5
+ * @description `CoreStore` is a store that contains all the necessary data for the SDK to work.
6
+ * `CoreStore` is a singleton and is created when the SDK is initialized. It includes the following stores:
7
+ * - `enabled` - the status of the SDK. The SDK is enabled when the `on` value is set.
8
+ * - `status` - the status of the SDK. Can be one of the following values: `disabled`, `initialization`, `ready`, `failed`, `suspended`.
9
+ * - `userKey` - the user key provided by the host.
10
+ * - `userToken` - the user token received from the StreamLayer after login.
11
+ * - `organizationSettings` - the organization settings.
12
+ * - `organizationAdvertising` - the organization advertising.
13
+ * - `streamSettings` - the stream settings.
14
+ * - `user` - the user data.
15
+ * - `userSettings` - the user settings.
16
+ * - `providerStreamId` - the event id provided by the host.
17
+ * - `slStreamId` - the event id received from the StreamLayer, resolved by the `providerStreamId`.
18
+ */
19
+ export class CoreStore extends AbstractStore {
20
+ stores;
21
+ constructor(transport) {
22
+ const storesObj = initializeStore(transport);
23
+ const store = mergeStores(storesObj);
24
+ super(store, 'core');
25
+ this.stores = storesObj;
26
+ }
27
+ getValue() {
28
+ throw new Error('Not implemented');
29
+ }
30
+ getValues() {
31
+ return this.stores;
32
+ }
33
+ setValue() {
34
+ throw new Error('Not implemented');
35
+ }
36
+ subscribe = (subscribes) => {
37
+ let storeKey;
38
+ for (storeKey in this.stores) {
39
+ const fn = subscribes[storeKey];
40
+ if (storeKey in subscribes && fn !== undefined) {
41
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
42
+ // @ts-ignore
43
+ this.stores[storeKey].subscribe(subscribes[storeKey]);
44
+ }
45
+ }
46
+ };
47
+ unsubscribe = () => {
48
+ const store = this.getStore();
49
+ return store.off();
50
+ };
51
+ }
package/package.json ADDED
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "@streamlayer/sdk-web-core",
3
+ "devDependencies": {
4
+ "tslib": "^2.6.2"
5
+ },
6
+ "peerDependencies": {
7
+ "@nanostores/query": "^0.2.8",
8
+ "nanostores": "^0.9.5",
9
+ "@streamlayer/sl-eslib": "^5.53.6",
10
+ "@streamlayer/sdk-web-interfaces": "^0.18.15",
11
+ "@streamlayer/sdk-web-storage": "^0.0.4",
12
+ "@streamlayer/sdk-web-api": "^0.0.1",
13
+ "@streamlayer/sdk-web-types": "^0.0.1"
14
+ },
15
+ "exports": {
16
+ ".": {
17
+ "types": "./lib/index.d.ts",
18
+ "import": "./lib/index.js",
19
+ "default": "./lib/index.js"
20
+ },
21
+ "./store": {
22
+ "types": "./lib/store/index.d.ts",
23
+ "import": "./lib/store/index.js",
24
+ "default": "./lib/store/index.js"
25
+ },
26
+ "./store/store": {
27
+ "types": "./lib/store/store.d.ts",
28
+ "import": "./lib/store/store.js",
29
+ "default": "./lib/store/store.js"
30
+ },
31
+ "./notifications": {
32
+ "types": "./lib/notifications/index.d.ts",
33
+ "import": "./lib/notifications/index.js",
34
+ "default": "./lib/notifications/index.js"
35
+ },
36
+ "./auth": {
37
+ "types": "./lib/auth/index.d.ts",
38
+ "import": "./lib/auth/index.js",
39
+ "default": "./lib/auth/index.js"
40
+ }
41
+ },
42
+ "version": "0.0.1",
43
+ "type": "module",
44
+ "main": "./lib/index.js",
45
+ "module": "./lib/index.js",
46
+ "typings": "./lib/index.d.ts",
47
+ "files": [
48
+ "lib/",
49
+ "package.json"
50
+ ]
51
+ }