@netless/app-embedded-page-sdk
SDK for storing shared replayable states and sending/receiving replayable events inside @netless/app-embedded-page
.
Install
npm add @netless/app-embedded-page-sdk
Example
import { createEmbeddedApp } from "@netless/app-embedded-page-sdk";
interface State {
count: number;
}
type Message = {
type: "click";
payload: { id: string };
};
const app = await createEmbeddedApp<State, Message>();
app.ensureState({ count: 0 });
app.state; // => { count: 0 }
app.setState({ count: 2 });
app.onStateChanged.addListener(diff => {
if (diff.count) {
// count: 0 -> 2
console.log("count:", diff.count.oldValue, "->", diff.count.newValue);
console.log(diff.count.newValue === app.state.count);
}
});
app.sendMessage({ type: "click", payload: { id: "item1" } });
app.onMessage.addListener(({ type, payload }) => {
if (type === "click") {
click(payload.id);
}
});
API
-
createEmbeddedApp()
Creates an embedded app instance.
Returns:
Promise<EmbeddedApp<State, Message>>
const app = await createEmbeddedApp();
-
app.appId
Type:
string
App ID. Each app is assigned with a unique ID on creation and will keep the same ID until destroyed.
-
app.state
Type:
State
Default:initialState
The synchronized state across all clients. To change it, call
app.setState()
. -
app.page
Type:
string | undefined
Current whiteboard scene. It works only if
scenePath
has been set when callingaddApp
. To switch between pages, callapp.setPage()
-
app.isWritable
Type:
boolean
When it is
false
, callingapp.setState()
,app.setPage()
,app.sendMessage()
has no effect. -
app.meta
Type:
{ sessionUID: number; uid: string; roomUUID?: string; userPayload: unknown }
Room information, including
-
sessionUID
: a unique number of current session. will change after refreshing. -
uid
: a unique id of current user passed in when callingjoinRoom()
. -
roomUUID
: current room's UUID. -
userPayload
: the object passed in when callingjoinRoom()
.
-
-
app.roomMembers
Type:
ReadonlyArray<{ sessionUID: number; uid: string; userPayload: unknown }>
All members in the room.
-
sessionUID
: a unique number of current session. will change after refreshing. -
uid
: a unique id of current user passed in when callingjoinRoom()
. -
userPayload
: the object passed in when callingjoinRoom()
.
-
-
app.ensureState(partialState)
Make sure
app.state
has some initial values, work as if:// this code won't work because app.state is readonly app.state = { ...partialState, ...app.state };
partialState
Type:
Partial<State>
app.state; // { a: 1 } app.ensureState({ a: 0, b: 0 }); app.state; // { a: 1, b: 0 }
-
app.setState(partialState)
Works like React's
setState
, it updatesapp.state
and synchronize it to other clients.When some field's value is
undefined
, it will be removed fromapp.state
.Important: Do not rely on the order of state changes:
-
app.setState()
altersapp.state
synchronously butonStateChanged
will wait until the data is successfully synced. - State syncing time span varies due to network status and data size. It is recommended to store only necessary data in the store.
partialState
Type:
Partial<State>
app.state; //=> { count: 0, a: 1 } app.setState({ count: app.state.count + 1, a: undefined, b: 2 }); app.state; //=> { count: 1, b: 2 }
-
-
app.setPage(page)
Change the whiteboard scene on top of your page.
page
Type:
string
Important: This argument must not include
/
.app.setPage("1");
-
app.sendMessage(message)
Broadcast a message to other clients.
message
Type: anything that can be serialized in JSON.
app.sendMessage("hello, world!");
-
app.moveCamera(partialCameraState)
Change the whiteboard scene's position on top of your page.
partialCameraState
Type:
Partial<{ x: number, y: number, scale: number }>
The default camera state is
{ x: 0, y: 0, scale: 1 }
, at the center of your page.app.moveCamera({ scale: 0.5 });
-
app.onStateChanged
It fires after someone called
app.setState()
(including the app itself).Type:
Emitter<{ [key: string]: { oldValue?, newValue? } }>
app.onStateChanged.addListener(diff => { console.log("state changed", app.state); });
-
app.onPageChanged
It fires after someone called
app.setPage()
(including the app itself).Type:
Emitter<{ oldValue?: string, newValue?: string }>
app.onPageChanged.addListener(diff => { console.log("switch page to", app.page); });
-
app.onWritableChanged
It fires when app writable state changes.
Type:
Emitter<{ oldValue?: boolean, newValue?: boolean }>
app.onWritableChanged.addListener(diff => { console.log("my writable becomes", app.isWritable); });
-
app.onRoomMembersChanged
It fires when room members changes.
Type:
Emitter<{ oldValue?: RoomMember[], newValue?: RoomMember[] }>
interface RoomMember { sessionUID: number; uid: string; userPayload: unknown; }
app.onRoomMembersChanged.addListener(diff => { console.log("room members changed", app.roomMembers); });
-
app.onMessage
It fires when receiving messages from other clients (when other clients called
app.sendMessage()
).Note: Won't receive
app.sendMessage()
messages sent by itself.Type:
Emitter<any>
app.onMessage.addListener(message => { console.log("received message", message); });
Licence
MIT @ netless