@blac/react
Advanced tools
Comparing version 0.0.4-0 to 0.0.13-0
@@ -5,3 +5,3 @@ import { Blac, BlocBase, BlocClass, ValueType } from 'blac'; | ||
declare const BlacApp: FC<{ | ||
children: JSX.Element; | ||
children: ReactNode; | ||
blac: Blac<any, any>; | ||
@@ -20,2 +20,6 @@ }>; | ||
} | ||
interface ProviderOptions<B> { | ||
bloc: BlocClass<B> | (() => B); | ||
debug?: boolean; | ||
} | ||
declare class BlacReact { | ||
@@ -27,3 +31,4 @@ blac: Blac<any, any>; | ||
constructor(blac: Blac<any, any>, blacContext: React.Context<Blac<any, any>>); | ||
static getInstance(): BlacReact; | ||
static safeGetInstance(): BlacReact | undefined; | ||
static getInstance(throwError?: boolean): BlacReact; | ||
setup(): void; | ||
@@ -53,13 +58,11 @@ /** | ||
providerUnmounted(providerId: string | undefined): void; | ||
readonly useLocalProvider: (options: { | ||
bloc: BlocBase<any> | (() => BlocBase<any>); | ||
debug?: boolean; | ||
}) => string | undefined; | ||
readonly useLocalProvider: (options: ProviderOptions<any>) => string | undefined; | ||
} | ||
declare const BlocProvider: FC<{ | ||
interface BlocProviderProps<B> { | ||
children?: ReactNode; | ||
bloc: (() => BlocBase<any>) | BlocBase<any>; | ||
bloc: BlocClass<B> | (() => B) | B; | ||
debug?: boolean; | ||
}>; | ||
} | ||
declare const BlocProvider: FC<BlocProviderProps<any>>; | ||
@@ -73,7 +76,3 @@ interface ExternalStore<B extends BlocBase<any>> { | ||
type BlocHookData<B extends BlocBase<S>, S> = [ | ||
value: ValueType<B>, | ||
instance: B | ||
]; | ||
interface BlocHookOptions { | ||
interface BlocResolveOptions { | ||
/** | ||
@@ -85,4 +84,12 @@ * Set to true if you want blac to automatically create a new instance of the bloc, | ||
} | ||
declare const useBloc: <B extends BlocBase<S>, S>(bloc: BlocClass<B> | (() => B), options?: BlocHookOptions) => BlocHookData<B, S>; | ||
type BlocHookData<B extends BlocBase<S>, S> = [ | ||
value: ValueType<B>, | ||
instance: B, | ||
Provider: FC<{ | ||
children: ReactNode; | ||
}> | ||
]; | ||
declare const useBloc: <B extends BlocBase<S>, S>(bloc: BlocClass<B> | (() => B), options?: BlocResolveOptions) => BlocHookData<B, S>; | ||
export { BlacApp, BlacReact, BlocProvider, ExternalStore, externalBlocStore, useBloc }; |
@@ -14,2 +14,3 @@ import React, { useContext, useMemo, useEffect, createContext, useSyncExternalStore } from 'react'; | ||
// treat this as singleton | ||
console.log('create', blac); | ||
const blacReact = blac.getPluginKey(BlacReact.pluginKey); | ||
@@ -24,4 +25,9 @@ // new setup | ||
} | ||
static getInstance() { | ||
static safeGetInstance() { | ||
const blac = globalThis.blac; | ||
const blacReact = blac?.getPluginKey(BlacReact.pluginKey); | ||
return blacReact; | ||
} | ||
static getInstance(throwError = true) { | ||
const blac = globalThis.blac; | ||
if (!blac) { | ||
@@ -117,3 +123,3 @@ throw new Error('BlacReact: blac instance not found'); | ||
providerUnmounted(providerId) { | ||
this.removeLocalBloc; | ||
this.removeLocalBloc(providerId); | ||
} | ||
@@ -170,3 +176,49 @@ useLocalProvider = (options) => { | ||
const useBloc = (bloc, options = {}) => { | ||
const resolveBloc = ({ bloc, blacInstance, localProviderKey, blacReact, create }) => { | ||
// check if its a create function or a class | ||
const isFunction = bloc instanceof Function; | ||
const isBloc = isFunction && bloc?.isBlacClass; | ||
const isLiveBloc = !isFunction && | ||
typeof bloc === 'object' && | ||
bloc?.isBlacLive; | ||
// if its a create function, call it | ||
if (!isBloc && isFunction) { | ||
return bloc(); | ||
} | ||
// if its a class | ||
if (isFunction && isBloc) { | ||
const blocClass = bloc; | ||
// check if the bloc is registered in the blac instance | ||
if (blacInstance) { | ||
const e = blacReact.getLocalBlocForProvider(localProviderKey, blocClass); | ||
if (e) { | ||
return e; | ||
} | ||
} | ||
// search in global blocs | ||
const globalBloc = blacReact.blac.getBloc(blocClass); | ||
if (globalBloc) { | ||
return globalBloc; | ||
} | ||
if (isLiveBloc) { | ||
return bloc; | ||
} | ||
console.log(typeof bloc, { | ||
isFunction, | ||
isBloc, | ||
isLiveBloc, | ||
bloc, | ||
create, | ||
}); | ||
// if it is not, check if we can create a new instance | ||
if (!create) { | ||
// creating it automatically should be opt-in | ||
throw new Error('useBloc: set create to true to create a new bloc when a class constructor is passed'); | ||
} | ||
// create a new instance -- this can cause issues if the constructor expects arguments | ||
const constructed = new blocClass(); | ||
return constructed; | ||
} | ||
}; | ||
const useResolvedBloc = (bloc, options = {}) => { | ||
const blacReact = BlacReact.getInstance(); | ||
@@ -176,34 +228,19 @@ const localProviderKey = blacReact.useLocalProviderKey(); | ||
const resolvedBloc = useMemo(() => { | ||
// check if its a create function or a class | ||
const isFunction = bloc instanceof Function; | ||
const isBloc = isFunction && bloc?.isBlacClass; | ||
// if its a create function, call it | ||
if (!isBloc && isFunction) { | ||
return bloc(); | ||
if (!blacReact || !localProviderKey) { | ||
return undefined; | ||
} | ||
// if its a class | ||
if (isFunction && isBloc) { | ||
const blocClass = bloc; | ||
// check if the bloc is registered in the blac instance | ||
if (blacInstance) { | ||
const e = blacReact.getLocalBlocForProvider(localProviderKey, blocClass); | ||
if (e) { | ||
return e; | ||
} | ||
} | ||
// search in global blocs | ||
const globalBloc = blacReact.blac.getBloc(blocClass); | ||
if (globalBloc) { | ||
return globalBloc; | ||
} | ||
// if it is not, check if we can create a new instance | ||
if (!options.create) { | ||
// creating it automatically should be opt-in | ||
throw new Error('useBloc: set create to true to create a new bloc when a class constructor is passed'); | ||
} | ||
// create a new instance -- this can cause issues if the constructor expects arguments | ||
const constructed = new blocClass(); | ||
return constructed; | ||
} | ||
}, []); | ||
return resolveBloc({ | ||
bloc, | ||
blacInstance, | ||
blacReact, | ||
localProviderKey, | ||
create: options.create ?? false | ||
}); | ||
}, [localProviderKey]); | ||
console.trace(resolvedBloc, options); | ||
return resolvedBloc; | ||
}; | ||
const useBloc = (bloc, options = {}) => { | ||
const resolvedBloc = useResolvedBloc(bloc, options); | ||
if (!resolvedBloc) { | ||
@@ -214,3 +251,8 @@ throw new Error('useBloc: bloc is undefined'); | ||
const state = useSyncExternalStore(subscribe, getSnapshot); | ||
return [state, resolvedBloc]; | ||
const Provider = useMemo(() => { | ||
return ({ children }) => { | ||
return React.createElement(BlocProvider, { bloc: resolvedBloc }, children); | ||
}; | ||
}, [resolvedBloc,]); | ||
return [state, resolvedBloc, Provider]; | ||
}; | ||
@@ -217,0 +259,0 @@ |
@@ -16,2 +16,3 @@ 'use strict'; | ||
// treat this as singleton | ||
console.log('create', blac); | ||
const blacReact = blac.getPluginKey(BlacReact.pluginKey); | ||
@@ -26,4 +27,9 @@ // new setup | ||
} | ||
static getInstance() { | ||
static safeGetInstance() { | ||
const blac = globalThis.blac; | ||
const blacReact = blac?.getPluginKey(BlacReact.pluginKey); | ||
return blacReact; | ||
} | ||
static getInstance(throwError = true) { | ||
const blac = globalThis.blac; | ||
if (!blac) { | ||
@@ -119,3 +125,3 @@ throw new Error('BlacReact: blac instance not found'); | ||
providerUnmounted(providerId) { | ||
this.removeLocalBloc; | ||
this.removeLocalBloc(providerId); | ||
} | ||
@@ -172,3 +178,49 @@ useLocalProvider = (options) => { | ||
const useBloc = (bloc, options = {}) => { | ||
const resolveBloc = ({ bloc, blacInstance, localProviderKey, blacReact, create }) => { | ||
// check if its a create function or a class | ||
const isFunction = bloc instanceof Function; | ||
const isBloc = isFunction && bloc?.isBlacClass; | ||
const isLiveBloc = !isFunction && | ||
typeof bloc === 'object' && | ||
bloc?.isBlacLive; | ||
// if its a create function, call it | ||
if (!isBloc && isFunction) { | ||
return bloc(); | ||
} | ||
// if its a class | ||
if (isFunction && isBloc) { | ||
const blocClass = bloc; | ||
// check if the bloc is registered in the blac instance | ||
if (blacInstance) { | ||
const e = blacReact.getLocalBlocForProvider(localProviderKey, blocClass); | ||
if (e) { | ||
return e; | ||
} | ||
} | ||
// search in global blocs | ||
const globalBloc = blacReact.blac.getBloc(blocClass); | ||
if (globalBloc) { | ||
return globalBloc; | ||
} | ||
if (isLiveBloc) { | ||
return bloc; | ||
} | ||
console.log(typeof bloc, { | ||
isFunction, | ||
isBloc, | ||
isLiveBloc, | ||
bloc, | ||
create, | ||
}); | ||
// if it is not, check if we can create a new instance | ||
if (!create) { | ||
// creating it automatically should be opt-in | ||
throw new Error('useBloc: set create to true to create a new bloc when a class constructor is passed'); | ||
} | ||
// create a new instance -- this can cause issues if the constructor expects arguments | ||
const constructed = new blocClass(); | ||
return constructed; | ||
} | ||
}; | ||
const useResolvedBloc = (bloc, options = {}) => { | ||
const blacReact = BlacReact.getInstance(); | ||
@@ -178,34 +230,19 @@ const localProviderKey = blacReact.useLocalProviderKey(); | ||
const resolvedBloc = React.useMemo(() => { | ||
// check if its a create function or a class | ||
const isFunction = bloc instanceof Function; | ||
const isBloc = isFunction && bloc?.isBlacClass; | ||
// if its a create function, call it | ||
if (!isBloc && isFunction) { | ||
return bloc(); | ||
if (!blacReact || !localProviderKey) { | ||
return undefined; | ||
} | ||
// if its a class | ||
if (isFunction && isBloc) { | ||
const blocClass = bloc; | ||
// check if the bloc is registered in the blac instance | ||
if (blacInstance) { | ||
const e = blacReact.getLocalBlocForProvider(localProviderKey, blocClass); | ||
if (e) { | ||
return e; | ||
} | ||
} | ||
// search in global blocs | ||
const globalBloc = blacReact.blac.getBloc(blocClass); | ||
if (globalBloc) { | ||
return globalBloc; | ||
} | ||
// if it is not, check if we can create a new instance | ||
if (!options.create) { | ||
// creating it automatically should be opt-in | ||
throw new Error('useBloc: set create to true to create a new bloc when a class constructor is passed'); | ||
} | ||
// create a new instance -- this can cause issues if the constructor expects arguments | ||
const constructed = new blocClass(); | ||
return constructed; | ||
} | ||
}, []); | ||
return resolveBloc({ | ||
bloc, | ||
blacInstance, | ||
blacReact, | ||
localProviderKey, | ||
create: options.create ?? false | ||
}); | ||
}, [localProviderKey]); | ||
console.trace(resolvedBloc, options); | ||
return resolvedBloc; | ||
}; | ||
const useBloc = (bloc, options = {}) => { | ||
const resolvedBloc = useResolvedBloc(bloc, options); | ||
if (!resolvedBloc) { | ||
@@ -216,3 +253,8 @@ throw new Error('useBloc: bloc is undefined'); | ||
const state = React.useSyncExternalStore(subscribe, getSnapshot); | ||
return [state, resolvedBloc]; | ||
const Provider = React.useMemo(() => { | ||
return ({ children }) => { | ||
return React.createElement(BlocProvider, { bloc: resolvedBloc }, children); | ||
}; | ||
}, [resolvedBloc,]); | ||
return [state, resolvedBloc, Provider]; | ||
}; | ||
@@ -219,0 +261,0 @@ |
{ | ||
"name": "@blac/react", | ||
"version": "0.0.4-0", | ||
"version": "0.0.13-0", | ||
"license": "MIT", | ||
@@ -5,0 +5,0 @@ "main": "dist/blac-react.js", |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
22612
582