diff --git a/objects/sandbox-example/src/App.svelte b/objects/sandbox-example/src/App.svelte
index 5aa24a6..0bf506a 100644
--- a/objects/sandbox-example/src/App.svelte
+++ b/objects/sandbox-example/src/App.svelte
@@ -1,9 +1,38 @@
-
+
+
+
diff --git a/packages/adapter/src/index.ts b/packages/adapter/src/index.ts
index d3ecd13..61c39d4 100644
--- a/packages/adapter/src/index.ts
+++ b/packages/adapter/src/index.ts
@@ -1,5 +1,5 @@
import pDefer, { DeferredPromise } from "p-defer";
-import { DataMessage, JSONSerializable, Token, TokenSchema, TransactionSchema, TransactionStateSchema, WakuObjectAdapter, WakuObjectArgs, WakuObjectContext, WakuObjectState } from './types'
+import { DataMessage, JSONSerializable, Token, TokenSchema, TransactionSchema, TransactionStateSchema, WakuObjectAdapter, WakuObjectArgs, WakuObjectContext, WakuObjectContextProps, WakuObjectState } from './types'
import { Contract } from "ethers";
interface AdapterRequestMessage {
@@ -31,11 +31,13 @@ export interface IframeDataMessage {
type: 'iframe-data-message'
message: DataMessage
state: WakuObjectState
+ context: WakuObjectContextProps
}
-export interface IframeStartMessage {
- type: 'iframe-start-message'
+export interface IframeContextChange {
+ type: 'iframe-context-change'
state: WakuObjectState
+ context: WakuObjectContextProps
}
// Store
@@ -72,6 +74,10 @@ function isIframeDataMessage(message: any): message is IframeDataMessage {
return typeof message == "object" && message?.type === "iframe-data-message"
}
+function isIframeContextChange(message: any): message is IframeContextChange {
+ return typeof message == "object" && message?.type === 'iframe-context-change'
+}
+
const isAdapterResponseMessage = (message: any): message is AdapterResponseMessage => {
return typeof message == "object" && message?.type === "adapter" && typeof message?.id === 'string';
};
@@ -166,7 +172,7 @@ export function makeWakuObjectAdapter(): WakuObjectAdapter {
}
}
-export function makeWakuObjectContext(adapter: WakuObjectAdapter): WakuObjectContext {
+export function makeWakuObjectContext(adapter: WakuObjectAdapter, contextProps?: Partial): WakuObjectContext {
async function send(data: JSONSerializable) {
const response = await adapterFunction('send')(JSON.stringify(data))
if (!response) {
@@ -189,6 +195,7 @@ export function makeWakuObjectContext(adapter: WakuObjectAdapter): WakuObjectCon
return {
...adapter,
+ ...contextProps,
send,
updateStore,
onViewChange,
@@ -197,12 +204,12 @@ export function makeWakuObjectContext(adapter: WakuObjectAdapter): WakuObjectCon
interface EventListenerOptions {
onDataMessage: (dataMessage: DataMessage, args: WakuObjectArgs) => Promise
+ onContextChange: (state: WakuObjectState, context: WakuObjectContextProps) => Promise
}
export function startEventListener(options: Partial) {
// Start listener
window.addEventListener("message", (event) => {
- console.debug('adapter sdk', { event })
// Check if the message came from the parent (chat app)
/*
if (event.origin !== "null" || event.source !== parent.contentWindow) {
@@ -215,7 +222,7 @@ export function startEventListener(options: Partial) {
if (isIframeDataMessage(data)) {
const message = data.message as DataMessage
const adapter = makeWakuObjectAdapter()
- const context = makeWakuObjectContext(adapter)
+ const context = makeWakuObjectContext(adapter, data.context)
const args: WakuObjectArgs = {
...context,
...data.state
@@ -226,6 +233,12 @@ export function startEventListener(options: Partial) {
return
}
+ if (isIframeContextChange(data)) {
+ if (options.onContextChange) {
+ options.onContextChange(data.state, data.context)
+ }
+ }
+
if (!isAdapterResponseMessage(data)) {
return;
}
@@ -245,4 +258,7 @@ export function startEventListener(options: Partial) {
defer.resolve(data.result.value);
});
+ // send `init` message after object side initialization is complete
+ // the host application will respond with the updated context
+ parent.postMessage({ type: 'init' }, '*')
}
diff --git a/packages/adapter/src/types.ts b/packages/adapter/src/types.ts
index 310cac0..d5f8528 100644
--- a/packages/adapter/src/types.ts
+++ b/packages/adapter/src/types.ts
@@ -69,7 +69,7 @@ export interface JSONArray extends Array {}
export type JSONValue = JSONPrimitive | JSONObject | JSONArray
-export type JSONSerializable = JSONValue
+export type JSONSerializable = JSONValue
export interface WakuObjectState {
readonly chatId: string
@@ -83,24 +83,29 @@ export interface WakuObjectState {
type StoreType = JSONSerializable
type DataMessageType = JSONSerializable
-export interface WakuObjectContext extends WakuObjectAdapter {
+export interface WakuObjectContextProps {
readonly store?: StoreType
+ readonly view?: string
+}
+
+export interface WakuObjectContext extends WakuObjectContextProps, WakuObjectAdapter {
updateStore: (updater: (state?: StoreType) => StoreType) => void
send: (data: DataMessageType) => Promise
- readonly view?: string
onViewChange: (view: string) => void
}
export interface WakuObjectArgs extends WakuObjectContext, WakuObjectState {}
-export interface WakuObjectDescriptor {
+interface WakuObjectMetadata {
readonly objectId: string
readonly name: string
readonly description: string
readonly logo: string
+}
+export interface WakuObjectDescriptor extends WakuObjectMetadata {
onMessage?: (message: DataMessage, args: WakuObjectArgs) => Promise
}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 9bdd2aa..380c606 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -1,5 +1,9 @@
lockfileVersion: '6.0'
+settings:
+ autoInstallPeers: true
+ excludeLinksFromLockfile: false
+
importers:
.: