@blockprotocol/core
Advanced tools
Comparing version 0.0.14 to 0.1.0-canary-20230220234726
@@ -22,3 +22,3 @@ import { CoreHandler } from "./core-handler"; | ||
* Receives the {@link EmbedderInitMessage} sent by the embedding application, | ||
* which is a series of payloads namespaced by service and message name. | ||
* which is a series of payloads namespaced by module and message name. | ||
* Calls the individual callbacks registered for each of these values. | ||
@@ -25,0 +25,0 @@ * |
@@ -47,3 +47,3 @@ "use strict"; | ||
* Receives the {@link EmbedderInitMessage} sent by the embedding application, | ||
* which is a series of payloads namespaced by service and message name. | ||
* which is a series of payloads namespaced by module and message name. | ||
* Calls the individual callbacks registered for each of these values. | ||
@@ -56,10 +56,10 @@ * | ||
const { data } = message; | ||
for (const serviceName of Object.keys(data)) { | ||
for (const messageName of Object.keys(data[serviceName])) { | ||
for (const moduleName of Object.keys(data)) { | ||
for (const messageName of Object.keys(data[moduleName])) { | ||
void this.callCallback({ | ||
message: { | ||
...message, | ||
data: data[serviceName][messageName], | ||
data: data[moduleName][messageName], | ||
messageName, | ||
service: serviceName, | ||
module: moduleName, | ||
}, | ||
@@ -66,0 +66,0 @@ }); |
@@ -25,3 +25,3 @@ import { CoreHandler } from "./core-handler"; | ||
* Sends a {@link EmbedderInitMessage} in response, which has all the messages | ||
* from registered services which can be sentOnInitialization. | ||
* from registered modules which can be sentOnInitialization. | ||
*/ | ||
@@ -28,0 +28,0 @@ protected processInitMessage(this: CoreEmbedderHandler, { event, message, }: { |
@@ -39,12 +39,12 @@ "use strict"; | ||
* Sends a {@link EmbedderInitMessage} in response, which has all the messages | ||
* from registered services which can be sentOnInitialization. | ||
* from registered modules which can be sentOnInitialization. | ||
*/ | ||
processInitMessage({ event, message, }) { | ||
this.updateDispatchElementFromEvent(event); | ||
// get the properties sent on initialization for any registered services | ||
// get the properties sent on initialization for any registered modules | ||
let data = this.initResponse; | ||
if (!data) { | ||
data = {}; | ||
for (const [serviceName, serviceInstance] of this.services) { | ||
data[serviceName] = serviceInstance.getInitPayload(); | ||
for (const [moduleName, moduleInstance] of this.modules) { | ||
data[moduleName] = moduleInstance.getInitPayload(); | ||
} | ||
@@ -51,0 +51,0 @@ } |
@@ -1,2 +0,2 @@ | ||
import { ServiceHandler } from "./service-handler"; | ||
import { ModuleHandler } from "./module-handler"; | ||
import { GenericMessageCallback, Message, MessageData, SendMessageArgs } from "./types"; | ||
@@ -6,3 +6,3 @@ /** | ||
* - listening for and dispatching messages via events | ||
* - registering callbacks from service handlers | ||
* - registering callbacks from module handlers | ||
* - processing incoming messages and calling callbacks as appropriate | ||
@@ -20,8 +20,8 @@ * | ||
private readonly defaultMessageCallback?; | ||
/** an object containing registered callbacks for messages, by service and message name */ | ||
private readonly messageCallbacksByService; | ||
/** an object containing registered callbacks for messages, by module and message name */ | ||
private readonly messageCallbacksByModule; | ||
/** a map of promise settlers and expected response names for requests, by requestId */ | ||
private readonly responseSettlersByRequestIdMap; | ||
/** the service handlers which have been registered to receive and send messages */ | ||
protected readonly services: Map<string, ServiceHandler>; | ||
/** the module handlers which have been registered to receive and send messages */ | ||
protected readonly modules: Map<string, ModuleHandler>; | ||
/** | ||
@@ -40,4 +40,4 @@ * the element on which messages will be listened for | ||
protected readonly sourceType: "block" | "embedder"; | ||
/** when this handler itself sends messages, serviceName identifies it as the core handler */ | ||
readonly serviceName: "core"; | ||
/** when this handler itself sends messages, moduleName identifies it as the core handler */ | ||
readonly moduleName: "core"; | ||
/** | ||
@@ -63,14 +63,14 @@ * Handles the initialization messages exchanged when a block registers a handler | ||
/** | ||
* Register a ServiceHandler for the given element. | ||
* Register a ModuleHandler for the given element. | ||
* Will re-use the CoreHandler if it exists for that element, or create a new one. | ||
* Currently the only way CoreHandlers may be instantiated | ||
* | ||
* [FUTURE]: there may be a need to instantiate CoreHandlers without any services | ||
* [FUTURE]: there may be a need to instantiate CoreHandlers without any modules | ||
*/ | ||
static registerService({ element, service, }: { | ||
static registerModule({ element, module, }: { | ||
element: HTMLElement; | ||
service: ServiceHandler; | ||
module: ModuleHandler; | ||
}): any; | ||
unregisterService({ service }: { | ||
service: ServiceHandler; | ||
unregisterModule({ module }: { | ||
module: ModuleHandler; | ||
}): void; | ||
@@ -93,11 +93,11 @@ protected constructor({ element, sourceType, }: { | ||
*/ | ||
registerCallback(this: CoreHandler, { callback, messageName, serviceName, }: { | ||
registerCallback(this: CoreHandler, { callback, messageName, moduleName, }: { | ||
callback: GenericMessageCallback; | ||
messageName: string; | ||
serviceName: string; | ||
moduleName: string; | ||
}): void; | ||
removeCallback(this: CoreHandler, { callback, messageName, serviceName, }: { | ||
removeCallback(this: CoreHandler, { callback, messageName, moduleName, }: { | ||
callback: GenericMessageCallback; | ||
messageName: string; | ||
serviceName: string; | ||
moduleName: string; | ||
}): void; | ||
@@ -104,0 +104,0 @@ sendMessage(this: CoreHandler, args: SendMessageArgs): void; |
@@ -8,3 +8,3 @@ "use strict"; | ||
* - listening for and dispatching messages via events | ||
* - registering callbacks from service handlers | ||
* - registering callbacks from module handlers | ||
* - processing incoming messages and calling callbacks as appropriate | ||
@@ -21,3 +21,3 @@ * | ||
"requestId" in message && | ||
"service" in message && | ||
"module" in message && | ||
"source" in message && | ||
@@ -27,20 +27,20 @@ "messageName" in message); | ||
/** | ||
* Register a ServiceHandler for the given element. | ||
* Register a ModuleHandler for the given element. | ||
* Will re-use the CoreHandler if it exists for that element, or create a new one. | ||
* Currently the only way CoreHandlers may be instantiated | ||
* | ||
* [FUTURE]: there may be a need to instantiate CoreHandlers without any services | ||
* [FUTURE]: there may be a need to instantiate CoreHandlers without any modules | ||
*/ | ||
static registerService({ element, service, }) { | ||
static registerModule({ element, module, }) { | ||
var _a; | ||
const { serviceName } = service; | ||
const { moduleName } = module; | ||
const handler = this.instanceMap.get(element) ?? Reflect.construct(this, [{ element }]); | ||
handler.services.set(serviceName, service); | ||
(_a = handler.messageCallbacksByService)[serviceName] ?? (_a[serviceName] = new Map()); | ||
handler.modules.set(moduleName, module); | ||
(_a = handler.messageCallbacksByModule)[moduleName] ?? (_a[moduleName] = new Map()); | ||
return handler; | ||
} | ||
unregisterService({ service }) { | ||
const { serviceName } = service; | ||
this.services.delete(serviceName); | ||
if (this.services.size === 0) { | ||
unregisterModule({ module }) { | ||
const { moduleName } = module; | ||
this.modules.delete(moduleName); | ||
if (this.modules.size === 0) { | ||
this.removeEventListeners(); | ||
@@ -55,10 +55,10 @@ CoreHandler.instanceMap.delete(this.listeningElement); | ||
this.messageQueue = []; | ||
/** an object containing registered callbacks for messages, by service and message name */ | ||
this.messageCallbacksByService = {}; | ||
/** an object containing registered callbacks for messages, by module and message name */ | ||
this.messageCallbacksByModule = {}; | ||
/** a map of promise settlers and expected response names for requests, by requestId */ | ||
this.responseSettlersByRequestIdMap = new Map(); | ||
/** the service handlers which have been registered to receive and send messages */ | ||
this.services = new Map(); | ||
/** when this handler itself sends messages, serviceName identifies it as the core handler */ | ||
this.serviceName = "core"; | ||
/** the module handlers which have been registered to receive and send messages */ | ||
this.modules = new Map(); | ||
/** when this handler itself sends messages, moduleName identifies it as the core handler */ | ||
this.moduleName = "core"; | ||
this.eventListener = (event) => { | ||
@@ -101,9 +101,9 @@ this.processReceivedMessage(event); | ||
*/ | ||
registerCallback({ callback, messageName, serviceName, }) { | ||
registerCallback({ callback, messageName, moduleName, }) { | ||
var _a; | ||
(_a = this.messageCallbacksByService)[serviceName] ?? (_a[serviceName] = new Map()); | ||
this.messageCallbacksByService[serviceName].set(messageName, callback); | ||
(_a = this.messageCallbacksByModule)[moduleName] ?? (_a[moduleName] = new Map()); | ||
this.messageCallbacksByModule[moduleName].set(messageName, callback); | ||
} | ||
removeCallback({ callback, messageName, serviceName, }) { | ||
const map = this.messageCallbacksByService[serviceName]; | ||
removeCallback({ callback, messageName, moduleName, }) { | ||
const map = this.messageCallbacksByModule[moduleName]; | ||
if (map?.get(messageName) === callback) { | ||
@@ -120,4 +120,4 @@ map.delete(messageName); | ||
const { partialMessage, requestId, sender } = args; | ||
if (!sender.serviceName) { | ||
throw new Error("Message sender has no serviceName set."); | ||
if (!sender.moduleName) { | ||
throw new Error("Message sender has no moduleName set."); | ||
} | ||
@@ -128,3 +128,3 @@ const fullMessage = { | ||
respondedToBy: "respondedToBy" in args ? args.respondedToBy : undefined, | ||
service: sender.serviceName, | ||
module: sender.moduleName, | ||
source: this.sourceType, | ||
@@ -172,4 +172,4 @@ }; | ||
async callCallback({ message }) { | ||
const { errors, messageName, data, requestId, respondedToBy, service } = message; | ||
const callback = this.messageCallbacksByService[service]?.get(messageName) ?? | ||
const { errors, messageName, data, requestId, respondedToBy, module } = message; | ||
const callback = this.messageCallbacksByModule[module]?.get(messageName) ?? | ||
this.defaultMessageCallback; | ||
@@ -184,5 +184,5 @@ if (respondedToBy && !callback) { | ||
if (respondedToBy) { | ||
const serviceHandler = this.services.get(service); | ||
if (!serviceHandler) { | ||
throw new Error(`Handler for service ${service} not registered.`); | ||
const moduleHandler = this.modules.get(module); | ||
if (!moduleHandler) { | ||
throw new Error(`Handler for module ${module} not registered.`); | ||
} | ||
@@ -198,3 +198,3 @@ try { | ||
requestId, | ||
sender: serviceHandler, | ||
sender: moduleHandler, | ||
}); | ||
@@ -234,4 +234,4 @@ } | ||
} | ||
const { errors, messageName, data, requestId, service } = message; | ||
if (service === "core" && | ||
const { errors, messageName, data, requestId, module } = message; | ||
if (module === "core" && | ||
((this.sourceType === "embedder" && messageName === "init") || | ||
@@ -245,3 +245,3 @@ (this.sourceType === "block" && messageName === "initResponse"))) { | ||
// eslint-disable-next-line no-console -- intentional feedback for users | ||
console.error(`Error calling callback for '${service}' service, for message '${messageName}: ${err}`); | ||
console.error(`Error calling callback for '${module}' module, for message '${messageName}: ${err}`); | ||
throw err; | ||
@@ -248,0 +248,0 @@ }); |
export { CoreBlockHandler } from "./core-block-handler"; | ||
export { CoreEmbedderHandler } from "./core-embedder-handler"; | ||
export { assignBlockProtocolGlobals, markBlockScripts, renderHtmlBlock, teardownBlockProtocol, } from "./html"; | ||
export { ServiceHandler } from "./service-handler"; | ||
export type { BlockMetadata, BlockMetadataRepository, BlockVariant, HtmlBlockDefinition, JsonArray, JsonObject, JsonValue, Message, MessageCallback, MessageData, MessageError, ServiceDefinition, ServiceMessageDefinition, UnknownRecord, } from "./types"; | ||
export { ModuleHandler } from "./module-handler"; | ||
export type { BlockMetadata, BlockMetadataRepository, BlockVariant, HtmlBlockDefinition, JsonArray, JsonObject, JsonValue, Message, MessageCallback, MessageData, MessageError, MessageReturn, ModuleDefinition, ModuleMessageDefinition, UnknownRecord, } from "./types"; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.ServiceHandler = exports.teardownBlockProtocol = exports.renderHtmlBlock = exports.markBlockScripts = exports.assignBlockProtocolGlobals = exports.CoreEmbedderHandler = exports.CoreBlockHandler = void 0; | ||
exports.ModuleHandler = exports.teardownBlockProtocol = exports.renderHtmlBlock = exports.markBlockScripts = exports.assignBlockProtocolGlobals = exports.CoreEmbedderHandler = exports.CoreBlockHandler = void 0; | ||
var core_block_handler_1 = require("./core-block-handler"); | ||
@@ -13,4 +13,4 @@ Object.defineProperty(exports, "CoreBlockHandler", { enumerable: true, get: function () { return core_block_handler_1.CoreBlockHandler; } }); | ||
Object.defineProperty(exports, "teardownBlockProtocol", { enumerable: true, get: function () { return html_1.teardownBlockProtocol; } }); | ||
var service_handler_1 = require("./service-handler"); | ||
Object.defineProperty(exports, "ServiceHandler", { enumerable: true, get: function () { return service_handler_1.ServiceHandler; } }); | ||
var module_handler_1 = require("./module-handler"); | ||
Object.defineProperty(exports, "ModuleHandler", { enumerable: true, get: function () { return module_handler_1.ModuleHandler; } }); | ||
//# sourceMappingURL=index.js.map |
import { RefObject } from "react"; | ||
import { ServiceHandler } from "./service-handler"; | ||
import { ModuleHandler } from "./module-handler"; | ||
import { GenericMessageCallback } from "./types"; | ||
type ServiceConstructor<T extends ServiceHandler> = { | ||
type ModuleConstructor<T extends ModuleHandler> = { | ||
new (arg: { | ||
@@ -10,4 +10,4 @@ callbacks?: Record<string, GenericMessageCallback>; | ||
}; | ||
export declare const useServiceConstructor: <T extends ServiceHandler>({ Handler, constructorArgs, ref, }: { | ||
Handler: ServiceConstructor<T>; | ||
export declare const useModuleConstructor: <T extends ModuleHandler>({ Handler, constructorArgs, ref, }: { | ||
Handler: ModuleConstructor<T>; | ||
constructorArgs?: { | ||
@@ -14,0 +14,0 @@ callbacks?: Record<string, GenericMessageCallback> | undefined; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.useServiceConstructor = void 0; | ||
exports.useModuleConstructor = void 0; | ||
const react_1 = require("react"); | ||
const useServiceConstructor = ({ Handler, constructorArgs, ref, }) => { | ||
const useModuleConstructor = ({ Handler, constructorArgs, ref, }) => { | ||
const previousRef = (0, react_1.useRef)(null); | ||
const initialisedRef = (0, react_1.useRef)(false); | ||
const [service, setService] = (0, react_1.useState)(() => new Handler(constructorArgs ?? {})); | ||
const [module, setModule] = (0, react_1.useState)(() => new Handler(constructorArgs ?? {})); | ||
const previousCallbacks = (0, react_1.useRef)(null); | ||
@@ -14,7 +14,7 @@ // Using a layout effect to ensure callbacks are updated as early as possible, | ||
if (previousCallbacks.current) { | ||
service.removeCallbacks(previousCallbacks.current); | ||
module.removeCallbacks(previousCallbacks.current); | ||
} | ||
previousCallbacks.current = constructorArgs?.callbacks ?? null; | ||
if (constructorArgs?.callbacks) { | ||
service.registerCallbacks(constructorArgs.callbacks); | ||
module.registerCallbacks(constructorArgs.callbacks); | ||
} | ||
@@ -28,3 +28,3 @@ }); | ||
if (previousRef.current) { | ||
service.destroy(); | ||
module.destroy(); | ||
} | ||
@@ -35,6 +35,6 @@ previousRef.current = ref.current; | ||
initialisedRef.current = true; | ||
service.initialize(ref.current); | ||
module.initialize(ref.current); | ||
} | ||
else { | ||
setService(new Handler({ | ||
setModule(new Handler({ | ||
element: ref.current, | ||
@@ -46,5 +46,5 @@ ...constructorArgs, | ||
}); | ||
return service; | ||
return module; | ||
}; | ||
exports.useServiceConstructor = useServiceConstructor; | ||
exports.useModuleConstructor = useModuleConstructor; | ||
//# sourceMappingURL=react.js.map |
import { CoreHandler } from "./core-handler"; | ||
import { ServiceHandler } from "./service-handler"; | ||
import { ModuleHandler } from "./module-handler"; | ||
export type UnknownRecord = Record<string, unknown>; | ||
@@ -115,15 +115,18 @@ export type JsonValue = null | boolean | number | string | JsonValue[] | JsonObject; | ||
respondedToBy?: string; | ||
service: string; | ||
module: string; | ||
source: "block" | "embedder"; | ||
timestamp: string; | ||
} | ||
export type MessageCallback<InputData, InputErrorCode extends string | null, ReturnData extends any | null = null, ReturnErrorCode extends ReturnData extends null ? null : string | null = null> = { | ||
(messageData: MessageData<InputData, InputErrorCode>): ReturnData extends null ? void : Promise<MessageData<ReturnData, ReturnErrorCode>>; | ||
export type MessageReturn<T extends any> = { | ||
data: T; | ||
}; | ||
export type MessageCallback<InputData, InputErrorCode extends string | null, ReturnData extends MessageReturn<any> | null = null, ReturnErrorCode extends ReturnData extends null ? null : string | null = null> = { | ||
(messageData: MessageData<InputData, InputErrorCode>): ReturnData extends null ? void : Promise<MessageData<(ReturnData extends null ? never : ReturnData)["data"], ReturnErrorCode>>; | ||
}; | ||
export type GenericMessageCallback = MessageCallback<any, string> | MessageCallback<any, string, any> | MessageCallback<any, null, any> | MessageCallback<any, null, any, string>; | ||
export type MessageCallbacksByService = { | ||
[serviceName: string]: Map<string, GenericMessageCallback> | undefined; | ||
export type MessageCallbacksByModule = { | ||
[moduleName: string]: Map<string, GenericMessageCallback> | undefined; | ||
}; | ||
export type EmbedderInitMessage = { | ||
[serviceName: string]: { | ||
[moduleName: string]: { | ||
[messageName: string]: any; | ||
@@ -136,3 +139,3 @@ }; | ||
respondedToBy?: string; | ||
sender: CoreHandler | ServiceHandler; | ||
sender: CoreHandler | ModuleHandler; | ||
}; | ||
@@ -147,7 +150,7 @@ type PromiseConstructorFnArgs = Parameters<ConstructorParameters<PromiseConstructorLike>[0]>; | ||
}>; | ||
export type ServiceMessageDefinition = { | ||
export type ModuleMessageDefinition = { | ||
messageName: string; | ||
description: string; | ||
source: "embedder" | "block"; | ||
data: Record<string, unknown>; | ||
data: JsonObject; | ||
sentOnInitialization?: boolean; | ||
@@ -157,7 +160,7 @@ errorCodes?: string[]; | ||
}; | ||
export type ServiceDefinition = { | ||
export type ModuleDefinition = { | ||
name: string; | ||
version: string; | ||
coreVersion: string; | ||
messages: ServiceMessageDefinition[]; | ||
messages: ModuleMessageDefinition[]; | ||
}; | ||
@@ -164,0 +167,0 @@ export type HtmlBlockDefinition = { |
@@ -22,3 +22,3 @@ import { CoreHandler } from "./core-handler"; | ||
* Receives the {@link EmbedderInitMessage} sent by the embedding application, | ||
* which is a series of payloads namespaced by service and message name. | ||
* which is a series of payloads namespaced by module and message name. | ||
* Calls the individual callbacks registered for each of these values. | ||
@@ -25,0 +25,0 @@ * |
@@ -44,3 +44,3 @@ import { CoreHandler } from "./core-handler"; | ||
* Receives the {@link EmbedderInitMessage} sent by the embedding application, | ||
* which is a series of payloads namespaced by service and message name. | ||
* which is a series of payloads namespaced by module and message name. | ||
* Calls the individual callbacks registered for each of these values. | ||
@@ -53,10 +53,10 @@ * | ||
const { data } = message; | ||
for (const serviceName of Object.keys(data)) { | ||
for (const messageName of Object.keys(data[serviceName])) { | ||
for (const moduleName of Object.keys(data)) { | ||
for (const messageName of Object.keys(data[moduleName])) { | ||
void this.callCallback({ | ||
message: { | ||
...message, | ||
data: data[serviceName][messageName], | ||
data: data[moduleName][messageName], | ||
messageName, | ||
service: serviceName, | ||
module: moduleName, | ||
}, | ||
@@ -63,0 +63,0 @@ }); |
@@ -25,3 +25,3 @@ import { CoreHandler } from "./core-handler"; | ||
* Sends a {@link EmbedderInitMessage} in response, which has all the messages | ||
* from registered services which can be sentOnInitialization. | ||
* from registered modules which can be sentOnInitialization. | ||
*/ | ||
@@ -28,0 +28,0 @@ protected processInitMessage(this: CoreEmbedderHandler, { event, message, }: { |
@@ -36,12 +36,12 @@ import { CoreHandler } from "./core-handler"; | ||
* Sends a {@link EmbedderInitMessage} in response, which has all the messages | ||
* from registered services which can be sentOnInitialization. | ||
* from registered modules which can be sentOnInitialization. | ||
*/ | ||
processInitMessage({ event, message, }) { | ||
this.updateDispatchElementFromEvent(event); | ||
// get the properties sent on initialization for any registered services | ||
// get the properties sent on initialization for any registered modules | ||
let data = this.initResponse; | ||
if (!data) { | ||
data = {}; | ||
for (const [serviceName, serviceInstance] of this.services) { | ||
data[serviceName] = serviceInstance.getInitPayload(); | ||
for (const [moduleName, moduleInstance] of this.modules) { | ||
data[moduleName] = moduleInstance.getInitPayload(); | ||
} | ||
@@ -48,0 +48,0 @@ } |
@@ -1,2 +0,2 @@ | ||
import { ServiceHandler } from "./service-handler"; | ||
import { ModuleHandler } from "./module-handler"; | ||
import { GenericMessageCallback, Message, MessageData, SendMessageArgs } from "./types"; | ||
@@ -6,3 +6,3 @@ /** | ||
* - listening for and dispatching messages via events | ||
* - registering callbacks from service handlers | ||
* - registering callbacks from module handlers | ||
* - processing incoming messages and calling callbacks as appropriate | ||
@@ -20,8 +20,8 @@ * | ||
private readonly defaultMessageCallback?; | ||
/** an object containing registered callbacks for messages, by service and message name */ | ||
private readonly messageCallbacksByService; | ||
/** an object containing registered callbacks for messages, by module and message name */ | ||
private readonly messageCallbacksByModule; | ||
/** a map of promise settlers and expected response names for requests, by requestId */ | ||
private readonly responseSettlersByRequestIdMap; | ||
/** the service handlers which have been registered to receive and send messages */ | ||
protected readonly services: Map<string, ServiceHandler>; | ||
/** the module handlers which have been registered to receive and send messages */ | ||
protected readonly modules: Map<string, ModuleHandler>; | ||
/** | ||
@@ -40,4 +40,4 @@ * the element on which messages will be listened for | ||
protected readonly sourceType: "block" | "embedder"; | ||
/** when this handler itself sends messages, serviceName identifies it as the core handler */ | ||
readonly serviceName: "core"; | ||
/** when this handler itself sends messages, moduleName identifies it as the core handler */ | ||
readonly moduleName: "core"; | ||
/** | ||
@@ -63,14 +63,14 @@ * Handles the initialization messages exchanged when a block registers a handler | ||
/** | ||
* Register a ServiceHandler for the given element. | ||
* Register a ModuleHandler for the given element. | ||
* Will re-use the CoreHandler if it exists for that element, or create a new one. | ||
* Currently the only way CoreHandlers may be instantiated | ||
* | ||
* [FUTURE]: there may be a need to instantiate CoreHandlers without any services | ||
* [FUTURE]: there may be a need to instantiate CoreHandlers without any modules | ||
*/ | ||
static registerService({ element, service, }: { | ||
static registerModule({ element, module, }: { | ||
element: HTMLElement; | ||
service: ServiceHandler; | ||
module: ModuleHandler; | ||
}): any; | ||
unregisterService({ service }: { | ||
service: ServiceHandler; | ||
unregisterModule({ module }: { | ||
module: ModuleHandler; | ||
}): void; | ||
@@ -93,11 +93,11 @@ protected constructor({ element, sourceType, }: { | ||
*/ | ||
registerCallback(this: CoreHandler, { callback, messageName, serviceName, }: { | ||
registerCallback(this: CoreHandler, { callback, messageName, moduleName, }: { | ||
callback: GenericMessageCallback; | ||
messageName: string; | ||
serviceName: string; | ||
moduleName: string; | ||
}): void; | ||
removeCallback(this: CoreHandler, { callback, messageName, serviceName, }: { | ||
removeCallback(this: CoreHandler, { callback, messageName, moduleName, }: { | ||
callback: GenericMessageCallback; | ||
messageName: string; | ||
serviceName: string; | ||
moduleName: string; | ||
}): void; | ||
@@ -104,0 +104,0 @@ sendMessage(this: CoreHandler, args: SendMessageArgs): void; |
@@ -5,3 +5,3 @@ import { v4 as uuid } from "uuid"; | ||
* - listening for and dispatching messages via events | ||
* - registering callbacks from service handlers | ||
* - registering callbacks from module handlers | ||
* - processing incoming messages and calling callbacks as appropriate | ||
@@ -18,3 +18,3 @@ * | ||
"requestId" in message && | ||
"service" in message && | ||
"module" in message && | ||
"source" in message && | ||
@@ -24,20 +24,20 @@ "messageName" in message); | ||
/** | ||
* Register a ServiceHandler for the given element. | ||
* Register a ModuleHandler for the given element. | ||
* Will re-use the CoreHandler if it exists for that element, or create a new one. | ||
* Currently the only way CoreHandlers may be instantiated | ||
* | ||
* [FUTURE]: there may be a need to instantiate CoreHandlers without any services | ||
* [FUTURE]: there may be a need to instantiate CoreHandlers without any modules | ||
*/ | ||
static registerService({ element, service, }) { | ||
static registerModule({ element, module, }) { | ||
var _a; | ||
const { serviceName } = service; | ||
const { moduleName } = module; | ||
const handler = this.instanceMap.get(element) ?? Reflect.construct(this, [{ element }]); | ||
handler.services.set(serviceName, service); | ||
(_a = handler.messageCallbacksByService)[serviceName] ?? (_a[serviceName] = new Map()); | ||
handler.modules.set(moduleName, module); | ||
(_a = handler.messageCallbacksByModule)[moduleName] ?? (_a[moduleName] = new Map()); | ||
return handler; | ||
} | ||
unregisterService({ service }) { | ||
const { serviceName } = service; | ||
this.services.delete(serviceName); | ||
if (this.services.size === 0) { | ||
unregisterModule({ module }) { | ||
const { moduleName } = module; | ||
this.modules.delete(moduleName); | ||
if (this.modules.size === 0) { | ||
this.removeEventListeners(); | ||
@@ -52,10 +52,10 @@ CoreHandler.instanceMap.delete(this.listeningElement); | ||
this.messageQueue = []; | ||
/** an object containing registered callbacks for messages, by service and message name */ | ||
this.messageCallbacksByService = {}; | ||
/** an object containing registered callbacks for messages, by module and message name */ | ||
this.messageCallbacksByModule = {}; | ||
/** a map of promise settlers and expected response names for requests, by requestId */ | ||
this.responseSettlersByRequestIdMap = new Map(); | ||
/** the service handlers which have been registered to receive and send messages */ | ||
this.services = new Map(); | ||
/** when this handler itself sends messages, serviceName identifies it as the core handler */ | ||
this.serviceName = "core"; | ||
/** the module handlers which have been registered to receive and send messages */ | ||
this.modules = new Map(); | ||
/** when this handler itself sends messages, moduleName identifies it as the core handler */ | ||
this.moduleName = "core"; | ||
this.eventListener = (event) => { | ||
@@ -98,9 +98,9 @@ this.processReceivedMessage(event); | ||
*/ | ||
registerCallback({ callback, messageName, serviceName, }) { | ||
registerCallback({ callback, messageName, moduleName, }) { | ||
var _a; | ||
(_a = this.messageCallbacksByService)[serviceName] ?? (_a[serviceName] = new Map()); | ||
this.messageCallbacksByService[serviceName].set(messageName, callback); | ||
(_a = this.messageCallbacksByModule)[moduleName] ?? (_a[moduleName] = new Map()); | ||
this.messageCallbacksByModule[moduleName].set(messageName, callback); | ||
} | ||
removeCallback({ callback, messageName, serviceName, }) { | ||
const map = this.messageCallbacksByService[serviceName]; | ||
removeCallback({ callback, messageName, moduleName, }) { | ||
const map = this.messageCallbacksByModule[moduleName]; | ||
if (map?.get(messageName) === callback) { | ||
@@ -117,4 +117,4 @@ map.delete(messageName); | ||
const { partialMessage, requestId, sender } = args; | ||
if (!sender.serviceName) { | ||
throw new Error("Message sender has no serviceName set."); | ||
if (!sender.moduleName) { | ||
throw new Error("Message sender has no moduleName set."); | ||
} | ||
@@ -125,3 +125,3 @@ const fullMessage = { | ||
respondedToBy: "respondedToBy" in args ? args.respondedToBy : undefined, | ||
service: sender.serviceName, | ||
module: sender.moduleName, | ||
source: this.sourceType, | ||
@@ -169,4 +169,4 @@ }; | ||
async callCallback({ message }) { | ||
const { errors, messageName, data, requestId, respondedToBy, service } = message; | ||
const callback = this.messageCallbacksByService[service]?.get(messageName) ?? | ||
const { errors, messageName, data, requestId, respondedToBy, module } = message; | ||
const callback = this.messageCallbacksByModule[module]?.get(messageName) ?? | ||
this.defaultMessageCallback; | ||
@@ -181,5 +181,5 @@ if (respondedToBy && !callback) { | ||
if (respondedToBy) { | ||
const serviceHandler = this.services.get(service); | ||
if (!serviceHandler) { | ||
throw new Error(`Handler for service ${service} not registered.`); | ||
const moduleHandler = this.modules.get(module); | ||
if (!moduleHandler) { | ||
throw new Error(`Handler for module ${module} not registered.`); | ||
} | ||
@@ -195,3 +195,3 @@ try { | ||
requestId, | ||
sender: serviceHandler, | ||
sender: moduleHandler, | ||
}); | ||
@@ -231,4 +231,4 @@ } | ||
} | ||
const { errors, messageName, data, requestId, service } = message; | ||
if (service === "core" && | ||
const { errors, messageName, data, requestId, module } = message; | ||
if (module === "core" && | ||
((this.sourceType === "embedder" && messageName === "init") || | ||
@@ -242,3 +242,3 @@ (this.sourceType === "block" && messageName === "initResponse"))) { | ||
// eslint-disable-next-line no-console -- intentional feedback for users | ||
console.error(`Error calling callback for '${service}' service, for message '${messageName}: ${err}`); | ||
console.error(`Error calling callback for '${module}' module, for message '${messageName}: ${err}`); | ||
throw err; | ||
@@ -245,0 +245,0 @@ }); |
export { CoreBlockHandler } from "./core-block-handler"; | ||
export { CoreEmbedderHandler } from "./core-embedder-handler"; | ||
export { assignBlockProtocolGlobals, markBlockScripts, renderHtmlBlock, teardownBlockProtocol, } from "./html"; | ||
export { ServiceHandler } from "./service-handler"; | ||
export type { BlockMetadata, BlockMetadataRepository, BlockVariant, HtmlBlockDefinition, JsonArray, JsonObject, JsonValue, Message, MessageCallback, MessageData, MessageError, ServiceDefinition, ServiceMessageDefinition, UnknownRecord, } from "./types"; | ||
export { ModuleHandler } from "./module-handler"; | ||
export type { BlockMetadata, BlockMetadataRepository, BlockVariant, HtmlBlockDefinition, JsonArray, JsonObject, JsonValue, Message, MessageCallback, MessageData, MessageError, MessageReturn, ModuleDefinition, ModuleMessageDefinition, UnknownRecord, } from "./types"; |
export { CoreBlockHandler } from "./core-block-handler"; | ||
export { CoreEmbedderHandler } from "./core-embedder-handler"; | ||
export { assignBlockProtocolGlobals, markBlockScripts, renderHtmlBlock, teardownBlockProtocol, } from "./html"; | ||
export { ServiceHandler } from "./service-handler"; | ||
export { ModuleHandler } from "./module-handler"; | ||
//# sourceMappingURL=index.js.map |
import { RefObject } from "react"; | ||
import { ServiceHandler } from "./service-handler"; | ||
import { ModuleHandler } from "./module-handler"; | ||
import { GenericMessageCallback } from "./types"; | ||
type ServiceConstructor<T extends ServiceHandler> = { | ||
type ModuleConstructor<T extends ModuleHandler> = { | ||
new (arg: { | ||
@@ -10,4 +10,4 @@ callbacks?: Record<string, GenericMessageCallback>; | ||
}; | ||
export declare const useServiceConstructor: <T extends ServiceHandler>({ Handler, constructorArgs, ref, }: { | ||
Handler: ServiceConstructor<T>; | ||
export declare const useModuleConstructor: <T extends ModuleHandler>({ Handler, constructorArgs, ref, }: { | ||
Handler: ModuleConstructor<T>; | ||
constructorArgs?: { | ||
@@ -14,0 +14,0 @@ callbacks?: Record<string, GenericMessageCallback> | undefined; |
import { useEffect, useLayoutEffect, useRef, useState } from "react"; | ||
export const useServiceConstructor = ({ Handler, constructorArgs, ref, }) => { | ||
export const useModuleConstructor = ({ Handler, constructorArgs, ref, }) => { | ||
const previousRef = useRef(null); | ||
const initialisedRef = useRef(false); | ||
const [service, setService] = useState(() => new Handler(constructorArgs ?? {})); | ||
const [module, setModule] = useState(() => new Handler(constructorArgs ?? {})); | ||
const previousCallbacks = useRef(null); | ||
@@ -11,7 +11,7 @@ // Using a layout effect to ensure callbacks are updated as early as possible, | ||
if (previousCallbacks.current) { | ||
service.removeCallbacks(previousCallbacks.current); | ||
module.removeCallbacks(previousCallbacks.current); | ||
} | ||
previousCallbacks.current = constructorArgs?.callbacks ?? null; | ||
if (constructorArgs?.callbacks) { | ||
service.registerCallbacks(constructorArgs.callbacks); | ||
module.registerCallbacks(constructorArgs.callbacks); | ||
} | ||
@@ -25,3 +25,3 @@ }); | ||
if (previousRef.current) { | ||
service.destroy(); | ||
module.destroy(); | ||
} | ||
@@ -32,6 +32,6 @@ previousRef.current = ref.current; | ||
initialisedRef.current = true; | ||
service.initialize(ref.current); | ||
module.initialize(ref.current); | ||
} | ||
else { | ||
setService(new Handler({ | ||
setModule(new Handler({ | ||
element: ref.current, | ||
@@ -43,4 +43,4 @@ ...constructorArgs, | ||
}); | ||
return service; | ||
return module; | ||
}; | ||
//# sourceMappingURL=react.js.map |
import { CoreHandler } from "./core-handler"; | ||
import { ServiceHandler } from "./service-handler"; | ||
import { ModuleHandler } from "./module-handler"; | ||
export type UnknownRecord = Record<string, unknown>; | ||
@@ -115,15 +115,18 @@ export type JsonValue = null | boolean | number | string | JsonValue[] | JsonObject; | ||
respondedToBy?: string; | ||
service: string; | ||
module: string; | ||
source: "block" | "embedder"; | ||
timestamp: string; | ||
} | ||
export type MessageCallback<InputData, InputErrorCode extends string | null, ReturnData extends any | null = null, ReturnErrorCode extends ReturnData extends null ? null : string | null = null> = { | ||
(messageData: MessageData<InputData, InputErrorCode>): ReturnData extends null ? void : Promise<MessageData<ReturnData, ReturnErrorCode>>; | ||
export type MessageReturn<T extends any> = { | ||
data: T; | ||
}; | ||
export type MessageCallback<InputData, InputErrorCode extends string | null, ReturnData extends MessageReturn<any> | null = null, ReturnErrorCode extends ReturnData extends null ? null : string | null = null> = { | ||
(messageData: MessageData<InputData, InputErrorCode>): ReturnData extends null ? void : Promise<MessageData<(ReturnData extends null ? never : ReturnData)["data"], ReturnErrorCode>>; | ||
}; | ||
export type GenericMessageCallback = MessageCallback<any, string> | MessageCallback<any, string, any> | MessageCallback<any, null, any> | MessageCallback<any, null, any, string>; | ||
export type MessageCallbacksByService = { | ||
[serviceName: string]: Map<string, GenericMessageCallback> | undefined; | ||
export type MessageCallbacksByModule = { | ||
[moduleName: string]: Map<string, GenericMessageCallback> | undefined; | ||
}; | ||
export type EmbedderInitMessage = { | ||
[serviceName: string]: { | ||
[moduleName: string]: { | ||
[messageName: string]: any; | ||
@@ -136,3 +139,3 @@ }; | ||
respondedToBy?: string; | ||
sender: CoreHandler | ServiceHandler; | ||
sender: CoreHandler | ModuleHandler; | ||
}; | ||
@@ -147,7 +150,7 @@ type PromiseConstructorFnArgs = Parameters<ConstructorParameters<PromiseConstructorLike>[0]>; | ||
}>; | ||
export type ServiceMessageDefinition = { | ||
export type ModuleMessageDefinition = { | ||
messageName: string; | ||
description: string; | ||
source: "embedder" | "block"; | ||
data: Record<string, unknown>; | ||
data: JsonObject; | ||
sentOnInitialization?: boolean; | ||
@@ -157,7 +160,7 @@ errorCodes?: string[]; | ||
}; | ||
export type ServiceDefinition = { | ||
export type ModuleDefinition = { | ||
name: string; | ||
version: string; | ||
coreVersion: string; | ||
messages: ServiceMessageDefinition[]; | ||
messages: ModuleMessageDefinition[]; | ||
}; | ||
@@ -164,0 +167,0 @@ export type HtmlBlockDefinition = { |
{ | ||
"name": "@blockprotocol/core", | ||
"version": "0.0.14", | ||
"version": "0.1.0-canary-20230220234726", | ||
"description": "Implementation of the Block Protocol Core specification for blocks and embedding applications", | ||
@@ -27,10 +27,12 @@ "keywords": [ | ||
"import": "./dist/esm/index.js", | ||
"require": "./dist/cjs/index.js" | ||
"require": "./dist/cjs/index.js", | ||
"default": "./dist/esm/index.js" | ||
}, | ||
"./react": { | ||
"import": "./dist/esm/react.js", | ||
"require": "./dist/cjs/react.js" | ||
"require": "./dist/cjs/react.js", | ||
"default": "./dist/esm/react.js" | ||
} | ||
}, | ||
"main": "./dist/cjs/index.js", | ||
"main": "./dist/esm/index.js", | ||
"module": "./dist/esm/index.js", | ||
@@ -37,0 +39,0 @@ "types": "./dist/esm/index.d.ts", |
@@ -5,4 +5,4 @@ # Block Protocol Core handler | ||
It is currently for use only as a dependency of packages implementing Block Protocol services, and to export basic types relating to block metadata. | ||
It is currently for use only as a dependency of packages implementing Block Protocol modules, and to export basic types relating to block metadata. | ||
See the `@blockprotocol/graph` package for an example. |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
256534
2645