@blac/react 0.0.3 → 0.0.13-0

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.
@@ -1,7 +1,10 @@
1
- import { Blac, BlocBase, ValueType, BlocClass } from 'blac';
1
+ import { Blac, BlocBase, BlocClass, ValueType } from 'blac';
2
2
  import React, { FC, ReactNode } from 'react';
3
3
 
4
- declare const BlacContext: React.Context<Blac<any, any> | null>;
4
+ declare const BlacApp: FC<{
5
+ children: ReactNode;
6
+ blac: Blac<any, any>;
7
+ }>;
5
8
 
6
9
  /**
7
10
  * Keep track of the hierarchy of Blac BlocProvider components, so that
@@ -13,30 +16,74 @@ interface ProviderItem {
13
16
  parent?: string;
14
17
  bloc: BlocBase<any>;
15
18
  }
19
+ interface ProviderOptions<B> {
20
+ bloc: BlocClass<B> | (() => B);
21
+ debug?: boolean;
22
+ }
23
+ declare class BlacReact {
24
+ blac: Blac<any, any>;
25
+ blacContext: React.Context<Blac<any, any>>;
26
+ localContextProvider: React.Context<BlocBase<any> | null>;
27
+ static pluginKey: string;
28
+ constructor(blac: Blac<any, any>, blacContext: React.Context<Blac<any, any>>);
29
+ static safeGetInstance(): BlacReact | undefined;
30
+ static getInstance(throwError?: boolean): BlacReact;
31
+ setup(): void;
32
+ /**
33
+ * React hook to get the bloc instance from the nearest BlocProvider
34
+ */
35
+ useLocalBlocContext(): BlocBase<any> | null;
36
+ private _contextLocalProviderKey;
37
+ get LocalProvider(): React.Provider<string>;
38
+ /**
39
+ * React hook to get the id from the nearest BlocProvider
40
+ */
41
+ useLocalProviderKey(): string;
42
+ addLocalBloc: (item: ProviderItem) => void;
43
+ removeLocalBloc: (id: string) => void;
44
+ createProviderId: () => string;
45
+ providerList: ProviderItem[];
46
+ getLocalBlocForProvider<B>(id: string, blocClass: BlocClass<B>): BlocBase<B> | undefined;
47
+ providerMounted(options: {
48
+ providerId: string;
49
+ localProviderKey?: string;
50
+ } & Parameters<BlacReact['useLocalProvider']>[0]): {
51
+ instance: BlocBase<any> | undefined;
52
+ destroyOnUnmount: boolean;
53
+ };
54
+ providerUnmounted(providerId: string | undefined): void;
55
+ readonly useLocalProvider: (options: ProviderOptions<any>) => string | undefined;
56
+ }
16
57
 
17
- declare const BlocProvider: FC<{
58
+ interface BlocProviderProps<B> {
18
59
  children?: ReactNode;
19
- bloc: (() => BlocBase<any>) | BlocBase<any>;
60
+ bloc: BlocClass<B> | (() => B) | B;
20
61
  debug?: boolean;
21
- }>;
62
+ }
63
+ declare const BlocProvider: FC<BlocProviderProps<any>>;
22
64
 
23
65
  interface ExternalStore<B extends BlocBase<any>> {
24
66
  subscribe: (onStoreChange: () => void) => () => void;
25
67
  getSnapshot: () => ValueType<B>;
26
68
  getServerSnapshot?: () => ValueType<B>;
27
69
  }
70
+ declare const externalBlocStore: <B extends BlocBase<any>>(bloc: B) => ExternalStore<B>;
28
71
 
29
- type BlocHookData<B extends BlocBase<S>, S> = [
30
- value: ValueType<B>,
31
- instance: B
32
- ];
33
- interface BlocHookOptions {
72
+ interface BlocResolveOptions {
34
73
  /**
35
74
  * Set to true if you want blac to automatically create a new instance of the bloc,
36
75
  * for this to work, pass the unconstructed class to the hook. The constructor should not expect any arguments.
37
76
  */
38
77
  create?: boolean;
39
78
  }
40
- declare const useBloc: <B extends BlocBase<S>, S>(bloc: BlocClass<B> | (() => B), options?: BlocHookOptions) => BlocHookData<B, S>;
41
79
 
42
- export { BlacContext, BlocHookData, BlocHookOptions, BlocProvider, ExternalStore, ProviderItem, useBloc };
80
+ type BlocHookData<B extends BlocBase<S>, S> = [
81
+ value: ValueType<B>,
82
+ instance: B,
83
+ Provider: FC<{
84
+ children: ReactNode;
85
+ }>
86
+ ];
87
+ declare const useBloc: <B extends BlocBase<S>, S>(bloc: BlocClass<B> | (() => B), options?: BlocResolveOptions) => BlocHookData<B, S>;
88
+
89
+ export { BlacApp, BlacReact, BlocProvider, ExternalStore, externalBlocStore, useBloc };
@@ -11,6 +11,7 @@ class BlacReact {
11
11
  static pluginKey = 'blacReact';
12
12
  constructor(blac, blacContext) {
13
13
  // treat this as singleton
14
+ console.log('create', blac);
14
15
  const blacReact = blac.getPluginKey(BlacReact.pluginKey);
15
16
  // new setup
16
17
  this.blac = blac;
@@ -20,7 +21,12 @@ class BlacReact {
20
21
  return blacReact;
21
22
  }
22
23
  }
23
- static getInstance() {
24
+ static safeGetInstance() {
25
+ const blac = globalThis.blac;
26
+ const blacReact = blac?.getPluginKey(BlacReact.pluginKey);
27
+ return blacReact;
28
+ }
29
+ static getInstance(throwError = true) {
24
30
  const blac = globalThis.blac;
25
31
  if (!blac) {
26
32
  throw new Error('BlacReact: blac instance not found');
@@ -112,7 +118,7 @@ class BlacReact {
112
118
  return { instance, destroyOnUnmount };
113
119
  }
114
120
  providerUnmounted(providerId) {
115
- this.removeLocalBloc;
121
+ this.removeLocalBloc(providerId);
116
122
  }
117
123
  useLocalProvider = (options) => {
118
124
  const [blocInstance, setBlocInstance] = React.useState(undefined);
@@ -133,7 +139,15 @@ class BlacReact {
133
139
  };
134
140
  }
135
141
 
136
- const BlacContext = createContext(null);
142
+ const BlacContext = createContext(null);
143
+ const BlacApp = (props) => {
144
+ const { children, blac } = props;
145
+ const blacApp = useMemo(() => new BlacReact(blac, BlacContext), [blac]);
146
+ if (!blacApp) {
147
+ throw new Error('BlacReact failed to initialize');
148
+ }
149
+ return React.createElement(BlacContext.Provider, { value: blac }, children);
150
+ };
137
151
 
138
152
  const BlocProvider = ({ children, bloc, debug }) => {
139
153
  const blacReact = BlacReact.getInstance();
@@ -156,50 +170,86 @@ const externalBlocStore = (bloc) => {
156
170
  };
157
171
  };
158
172
 
159
- const useBloc = (bloc, options = {}) => {
173
+ const resolveBloc = ({ bloc, blacInstance, localProviderKey, blacReact, create }) => {
174
+ // check if its a create function or a class
175
+ const isFunction = bloc instanceof Function;
176
+ const isBloc = isFunction && bloc?.isBlacClass;
177
+ const isLiveBloc = !isFunction &&
178
+ typeof bloc === 'object' &&
179
+ bloc?.isBlacLive;
180
+ // if its a create function, call it
181
+ if (!isBloc && isFunction) {
182
+ return bloc();
183
+ }
184
+ // if its a class
185
+ if (isFunction && isBloc) {
186
+ const blocClass = bloc;
187
+ // check if the bloc is registered in the blac instance
188
+ if (blacInstance) {
189
+ const e = blacReact.getLocalBlocForProvider(localProviderKey, blocClass);
190
+ if (e) {
191
+ return e;
192
+ }
193
+ }
194
+ // search in global blocs
195
+ const globalBloc = blacReact.blac.getBloc(blocClass);
196
+ if (globalBloc) {
197
+ return globalBloc;
198
+ }
199
+ if (isLiveBloc) {
200
+ return bloc;
201
+ }
202
+ console.log(typeof bloc, {
203
+ isFunction,
204
+ isBloc,
205
+ isLiveBloc,
206
+ bloc,
207
+ create,
208
+ });
209
+ // if it is not, check if we can create a new instance
210
+ if (!create) {
211
+ // creating it automatically should be opt-in
212
+ throw new Error('useBloc: set create to true to create a new bloc when a class constructor is passed');
213
+ }
214
+ // create a new instance -- this can cause issues if the constructor expects arguments
215
+ const constructed = new blocClass();
216
+ return constructed;
217
+ }
218
+ };
219
+ const useResolvedBloc = (bloc, options = {}) => {
160
220
  const blacReact = BlacReact.getInstance();
161
221
  const localProviderKey = blacReact.useLocalProviderKey();
162
222
  const blacInstance = useContext(BlacContext);
163
223
  const resolvedBloc = useMemo(() => {
164
- // check if its a create function or a class
165
- const isFunction = bloc instanceof Function;
166
- const isBloc = isFunction && bloc?.isBlacClass;
167
- // if its a create function, call it
168
- if (!isBloc && isFunction) {
169
- return bloc();
224
+ if (!blacReact || !localProviderKey) {
225
+ return undefined;
170
226
  }
171
- // if its a class
172
- if (isFunction && isBloc) {
173
- const blocClass = bloc;
174
- // check if the bloc is registered in the blac instance
175
- if (blacInstance) {
176
- const e = blacReact.getLocalBlocForProvider(localProviderKey, blocClass);
177
- if (e) {
178
- return e;
179
- }
180
- }
181
- // search in global blocs
182
- const globalBloc = blacReact.blac.getBloc(blocClass);
183
- if (globalBloc) {
184
- return globalBloc;
185
- }
186
- // if it is not, check if we can create a new instance
187
- if (!options.create) {
188
- // creating it automatically should be opt-in
189
- throw new Error('useBloc: set create to true to create a new bloc when a class constructor is passed');
190
- }
191
- // create a new instance -- this can cause issues if the constructor expects arguments
192
- const constructed = new blocClass();
193
- return constructed;
194
- }
195
- }, []);
227
+ return resolveBloc({
228
+ bloc,
229
+ blacInstance,
230
+ blacReact,
231
+ localProviderKey,
232
+ create: options.create ?? false
233
+ });
234
+ }, [localProviderKey]);
235
+ console.trace(resolvedBloc, options);
236
+ return resolvedBloc;
237
+ };
238
+
239
+ const useBloc = (bloc, options = {}) => {
240
+ const resolvedBloc = useResolvedBloc(bloc, options);
196
241
  if (!resolvedBloc) {
197
242
  throw new Error('useBloc: bloc is undefined');
198
243
  }
199
244
  const { subscribe, getSnapshot } = useMemo(() => externalBlocStore(resolvedBloc), [resolvedBloc]);
200
245
  const state = useSyncExternalStore(subscribe, getSnapshot);
201
- return [state, resolvedBloc];
246
+ const Provider = useMemo(() => {
247
+ return ({ children }) => {
248
+ return React.createElement(BlocProvider, { bloc: resolvedBloc }, children);
249
+ };
250
+ }, [resolvedBloc,]);
251
+ return [state, resolvedBloc, Provider];
202
252
  };
203
253
 
204
- export { BlacContext, BlocProvider, useBloc };
254
+ export { BlacApp, BlacReact, BlocProvider, externalBlocStore, useBloc };
205
255
  //# sourceMappingURL=blac-react.esm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"blac-react.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"blac-react.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -13,6 +13,7 @@ class BlacReact {
13
13
  static pluginKey = 'blacReact';
14
14
  constructor(blac, blacContext) {
15
15
  // treat this as singleton
16
+ console.log('create', blac);
16
17
  const blacReact = blac.getPluginKey(BlacReact.pluginKey);
17
18
  // new setup
18
19
  this.blac = blac;
@@ -22,7 +23,12 @@ class BlacReact {
22
23
  return blacReact;
23
24
  }
24
25
  }
25
- static getInstance() {
26
+ static safeGetInstance() {
27
+ const blac = globalThis.blac;
28
+ const blacReact = blac?.getPluginKey(BlacReact.pluginKey);
29
+ return blacReact;
30
+ }
31
+ static getInstance(throwError = true) {
26
32
  const blac = globalThis.blac;
27
33
  if (!blac) {
28
34
  throw new Error('BlacReact: blac instance not found');
@@ -114,7 +120,7 @@ class BlacReact {
114
120
  return { instance, destroyOnUnmount };
115
121
  }
116
122
  providerUnmounted(providerId) {
117
- this.removeLocalBloc;
123
+ this.removeLocalBloc(providerId);
118
124
  }
119
125
  useLocalProvider = (options) => {
120
126
  const [blocInstance, setBlocInstance] = React.useState(undefined);
@@ -135,7 +141,15 @@ class BlacReact {
135
141
  };
136
142
  }
137
143
 
138
- const BlacContext = React.createContext(null);
144
+ const BlacContext = React.createContext(null);
145
+ const BlacApp = (props) => {
146
+ const { children, blac } = props;
147
+ const blacApp = React.useMemo(() => new BlacReact(blac, BlacContext), [blac]);
148
+ if (!blacApp) {
149
+ throw new Error('BlacReact failed to initialize');
150
+ }
151
+ return React.createElement(BlacContext.Provider, { value: blac }, children);
152
+ };
139
153
 
140
154
  const BlocProvider = ({ children, bloc, debug }) => {
141
155
  const blacReact = BlacReact.getInstance();
@@ -158,52 +172,90 @@ const externalBlocStore = (bloc) => {
158
172
  };
159
173
  };
160
174
 
161
- const useBloc = (bloc, options = {}) => {
175
+ const resolveBloc = ({ bloc, blacInstance, localProviderKey, blacReact, create }) => {
176
+ // check if its a create function or a class
177
+ const isFunction = bloc instanceof Function;
178
+ const isBloc = isFunction && bloc?.isBlacClass;
179
+ const isLiveBloc = !isFunction &&
180
+ typeof bloc === 'object' &&
181
+ bloc?.isBlacLive;
182
+ // if its a create function, call it
183
+ if (!isBloc && isFunction) {
184
+ return bloc();
185
+ }
186
+ // if its a class
187
+ if (isFunction && isBloc) {
188
+ const blocClass = bloc;
189
+ // check if the bloc is registered in the blac instance
190
+ if (blacInstance) {
191
+ const e = blacReact.getLocalBlocForProvider(localProviderKey, blocClass);
192
+ if (e) {
193
+ return e;
194
+ }
195
+ }
196
+ // search in global blocs
197
+ const globalBloc = blacReact.blac.getBloc(blocClass);
198
+ if (globalBloc) {
199
+ return globalBloc;
200
+ }
201
+ if (isLiveBloc) {
202
+ return bloc;
203
+ }
204
+ console.log(typeof bloc, {
205
+ isFunction,
206
+ isBloc,
207
+ isLiveBloc,
208
+ bloc,
209
+ create,
210
+ });
211
+ // if it is not, check if we can create a new instance
212
+ if (!create) {
213
+ // creating it automatically should be opt-in
214
+ throw new Error('useBloc: set create to true to create a new bloc when a class constructor is passed');
215
+ }
216
+ // create a new instance -- this can cause issues if the constructor expects arguments
217
+ const constructed = new blocClass();
218
+ return constructed;
219
+ }
220
+ };
221
+ const useResolvedBloc = (bloc, options = {}) => {
162
222
  const blacReact = BlacReact.getInstance();
163
223
  const localProviderKey = blacReact.useLocalProviderKey();
164
224
  const blacInstance = React.useContext(BlacContext);
165
225
  const resolvedBloc = React.useMemo(() => {
166
- // check if its a create function or a class
167
- const isFunction = bloc instanceof Function;
168
- const isBloc = isFunction && bloc?.isBlacClass;
169
- // if its a create function, call it
170
- if (!isBloc && isFunction) {
171
- return bloc();
226
+ if (!blacReact || !localProviderKey) {
227
+ return undefined;
172
228
  }
173
- // if its a class
174
- if (isFunction && isBloc) {
175
- const blocClass = bloc;
176
- // check if the bloc is registered in the blac instance
177
- if (blacInstance) {
178
- const e = blacReact.getLocalBlocForProvider(localProviderKey, blocClass);
179
- if (e) {
180
- return e;
181
- }
182
- }
183
- // search in global blocs
184
- const globalBloc = blacReact.blac.getBloc(blocClass);
185
- if (globalBloc) {
186
- return globalBloc;
187
- }
188
- // if it is not, check if we can create a new instance
189
- if (!options.create) {
190
- // creating it automatically should be opt-in
191
- throw new Error('useBloc: set create to true to create a new bloc when a class constructor is passed');
192
- }
193
- // create a new instance -- this can cause issues if the constructor expects arguments
194
- const constructed = new blocClass();
195
- return constructed;
196
- }
197
- }, []);
229
+ return resolveBloc({
230
+ bloc,
231
+ blacInstance,
232
+ blacReact,
233
+ localProviderKey,
234
+ create: options.create ?? false
235
+ });
236
+ }, [localProviderKey]);
237
+ console.trace(resolvedBloc, options);
238
+ return resolvedBloc;
239
+ };
240
+
241
+ const useBloc = (bloc, options = {}) => {
242
+ const resolvedBloc = useResolvedBloc(bloc, options);
198
243
  if (!resolvedBloc) {
199
244
  throw new Error('useBloc: bloc is undefined');
200
245
  }
201
246
  const { subscribe, getSnapshot } = React.useMemo(() => externalBlocStore(resolvedBloc), [resolvedBloc]);
202
247
  const state = React.useSyncExternalStore(subscribe, getSnapshot);
203
- return [state, resolvedBloc];
248
+ const Provider = React.useMemo(() => {
249
+ return ({ children }) => {
250
+ return React.createElement(BlocProvider, { bloc: resolvedBloc }, children);
251
+ };
252
+ }, [resolvedBloc,]);
253
+ return [state, resolvedBloc, Provider];
204
254
  };
205
255
 
206
- exports.BlacContext = BlacContext;
256
+ exports.BlacApp = BlacApp;
257
+ exports.BlacReact = BlacReact;
207
258
  exports.BlocProvider = BlocProvider;
259
+ exports.externalBlocStore = externalBlocStore;
208
260
  exports.useBloc = useBloc;
209
261
  //# sourceMappingURL=blac-react.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"blac-react.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"blac-react.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blac/react",
3
- "version": "0.0.3",
3
+ "version": "0.0.13-0",
4
4
  "license": "MIT",
5
5
  "main": "dist/blac-react.js",
6
6
  "module": "dist/blac-react.esm.js",