# API
# Basic Types
type State = Record<string, any>;
type Events = Record<string, (...args: any[]) => void>;
type Methods = Record<string, (...args: any[]) => any>;
type BlockDeclare = Partial<{
state: State;
events: Events;
methods: Methods;
}>;
# createBlock
Type:
<T extends BlockDeclare>(name: string) => CreatedBlock<T['state'], T['events'], T['methods'], T['exports']>
Description: Creates a Block, accepting a globally unique block name as a parameter, and returns a
CreatedBlock
instance.Example:
import { createBlock } from "@rallie/block"; interface MyBlock { state: { count: number; user: { name: string; }; }, events: { incrementCount: () => void; }, methods: { login: () => void; logout: () => void; }; } const myBlock = createBlock<MyBlock>("my-block");
# CreatedBlock
# name
- Type:
string
- Description: The name of the Block.
# state
- Type:
State
- Description: The state of the Block, which is read-only. To modify the state of a Block, the setState method must be used.
# methods
Type:
Methods
Description: The method invoker of the Block, which is read-only. To add methods to a Block, the addMethods method must be used.
Example:
// Add methods block.addMethods({ login: async () => { const success = await requestLogin(); return success; }, }); // Invoke method block.methods.login().then((success) => { if (success) { alert("Login successfully"); } });
# events
Type:
Events
Description: The event invoker of the Block, which is read-only. To add event listeners to a Block, the listenEvents method must be used.
Example:
// Listen to events block.listenEvents({ themeChange: (themeColor) => { doChangeTheme(themeColor); }, }); // Trigger event block.events.themeChange("red");
# initState
- Type:
(value: State, isPrivate: boolean = false) => CreatedBlock
- Description: Initializes the state of the Block. A Block can only be initialized once. Calling
initState
multiple times will throw an error. If you want the state to be unmodifiable by other Blocks, passtrue
as the second parameter to indicate that the state is set as private.
# setState
Type:
((action: string, state: State) => void | Promise<void>) => Promise<void>
Description: Modifies the state of the Block. The first parameter is a description of this operation.
Example:
// Synchronously modify state block.setState("add the count synchronously", (state) => { state.count++; }); // Asynchronously modify state await block.setState("add the count asynchronously", async (state) => { const userInfo = await requestLogIn(); state.user = userInfo; });
# watchState
Type:
((state: State) => any) => Watcher
Description: Listens to changes in the Block's state, implemented based on the
effect
method of@vue/reactivity
. See examples for specific usage.Example:
Chained calling to watch state
// Watch state const unwatch = block .watchState((state) => state.count) .do((newCount, oldCount) => { console.log(newCount, oldCount); }); // Unwatch unwatch();
watchEffect
// Watch state const watcher = block.watchState((state) => { console.log(state.count, state.user); }); // Unwatch watcher.unwatch();
# listenEvents
- Type:
(events: Partial<Events>) => (eventName?: string) => void
- Description: Adds event listeners to the Block, and the return value is a function to cancel the event listening. The block name of the event caller can be obtained from the
this
context of the listening callback. - Example:
- Listen to events:
const cancelEvents = block.listenEvents({ changeTheme(this: { trigger: string }, themeColor) { console.log(`Event caller is ${this.trigger}`) doChangeTheme(themeColor); }, changeLanguage: (lang) => { doChangeLanguage(lang); }, });
- Cancel listening to all events:
cancelEvents();
- Cancel listening to a single event
cancelEvents("changeTheme");
- Listen to events:
# addMethods
- Type:
(methods: Partial<Methods>) => (methodName?: string) => void
- Description: Adds methods to the Block, and the return value is a function to remove the methods. The block name of the event caller can be obtained from the
this
context of the method callback. - Example:
- Add methods:
const removeMethods = block.addMethods({ async logIn(this: { trigger: string }) => { console.log(`Event caller is ${this.trigger}`) await requestLogIn(); }, logOut: async () => { await requestLogOut(); }, });
- Remove all methods:
removeMethods();
- Remove a single method
removeMethods("logIn");
- Add methods:
# load
- Type:
(name: string) => Promise<void>
- Description: Loads the resources of a Block, with the argument being the name of the Block to be loaded.
# activate
- Type:
(name: string) => Promise<void>
- Description: Activates a Block, with the argument being the name of the Block to be activated.
# connect
- Type:
<T extends BlockDeclare>(name: string) => ConnectedBlock<T>
- Description: Connects to a Block, receiving the name of the Block to be connected as the only parameter, and returns a ConnectedBlock that allows the use of the connected Block's state, events, and methods.
- Example:
interface RemoteBlock { state: { count: number, user: { name: string } }, events: { incrementCount: () => void }, methods: { login: () => void, logout: () => void }, exports: { text: string } } const connectedBlock = block.connect<RemoteBlock>("remote");
The connect method will return a ConnectedBlock
. Its state, event, and method-related APIs are a subset of the CreatedBlock APIs, including name, state, events, methods, setState, watchState, and listenEvents.
TIP
If the connected Block declares its state as private, calling setState
to change the Block's state via ConnectedBlock
will result in an error.
The usage of the above properties and methods is completely consistent with the usage of CreatedBlock.
TIP
For a ConnectedBlock, to use its state, call its methods, or import its exposed objects, you should ensure that its state has been initialized, methods have been added, and objects have been exported. The connect operation does not load or activate the Block to be connected, so you should declare the Block to be connected as the current Block's association or dependency, or manually load or activate the Block to be connected.
# run
- Type:
(callback: (env: Env) => void | Promise<void>) => Promise<void>
- Description: Executes the passed callback function. The current Block's runtime environment can be obtained in the callback parameter, see Env.
# Env
The runtime environment object of a Block, which can be obtained in the callback of the run method.
# isEntry
- Type:
boolean
- Description: Whether it is the entry environment. If a Block is the first application created in the application cluster, then when executing the Block's
run
method, its callback parameterenv.isEntry
istrue
, otherwise it isfalse
.
# freeze
- Type:
() => void
- Description: Freezes the current runtime environment, which is only effective when
env.isEntry
istrue
. After the runtime environment is frozen, the middleware and configurations applied by non-entry environment Blocks will not take effect.
# unfreeze
- Type:
() => void
- Description: Unfreezes the current runtime environment, which is only effective when
env.isEntry
istrue
.
# use
- Type:
(middleware: (ctx: Context, next: () => Promise<void>) => void) => void
- Description: Applies resource loading middleware, usage refers to middleware, the type of context is:
interface Context { name: string; // The name of the Block to be loaded conf: ConfType; // The configuration of the runtime environment, refer to env.conf loadScript: ( script: Partial<HTMLScriptElement> | string | HTMLScriptElement ) => Promise<void>; // Method to insert script tags loadLink: ( link: Partial<HTMLLinkElement> | string | HTMLLinkElement ) => Promise<void>; // Method to insert link tags [other: string]: any; // Middleware can add methods and properties to context }
# conf
- Type:
interface ConfType { assets?: Record< string, { js: Array<string>; css: Array<string>; } >; [other: string]: any; }
- Description: The global configuration of the runtime environment, which can be configured through
env.config
. Theassets
property is the resource path information of the application cluster. The innermost middleware of rallie's onion middleware model will look for and load application resources inassets
based on the Block's name.
# config
- Type:
(conf: ConfType) => void
- Description: Configures the runtime environment. When configuring
assets
, the information will be appended and not overwritten.env.config({ assets: { bar: { js: ["bar.js"], }, }, }); env.config({ assets: { foo: { js: ["foo.js"], }, }, }); console.log(env.conf.assets); /* The result will be printed as: { bar: { js: ['bar.js'] }, foo: { js: ['foo.js'] } } */