convex
Version:
Client for the Convex Cloud
323 lines (322 loc) • 10.1 kB
JavaScript
;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var __publicField = (obj, key, value) => {
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
var components_exports = {};
__export(components_exports, {
componentsGeneric: () => componentsGeneric,
createComponentArg: () => createComponentArg,
createFunctionHandle: () => createFunctionHandle,
currentSystemUdfInComponent: () => currentSystemUdfInComponent,
defineApp: () => defineApp,
defineComponent: () => defineComponent,
extractReferencePath: () => extractReferencePath,
isFunctionHandle: () => isFunctionHandle,
toReferencePath: () => toReferencePath
});
module.exports = __toCommonJS(components_exports);
var import_values = require("../../values/index.js");
var import_actions_impl = require("../impl/actions_impl.js");
var import_syscall = require("../impl/syscall.js");
var _a;
const toReferencePath = Symbol.for("toReferencePath");
function extractReferencePath(reference) {
return reference[toReferencePath] ?? null;
}
function isFunctionHandle(s) {
return s.startsWith("function://");
}
async function createFunctionHandle(functionReference) {
const address = (0, import_actions_impl.getFunctionAddress)(functionReference);
return await (0, import_syscall.performAsyncSyscall)("1.0/createFunctionHandle", { ...address });
}
class InstalledComponent {
constructor(definition, name) {
/**
* @internal
*/
__publicField(this, "_definition");
/**
* @internal
*/
__publicField(this, "_name");
/**
* @internal
*/
__publicField(this, _a);
this._definition = definition;
this._name = name;
this[toReferencePath] = `_reference/childComponent/${name}`;
}
get exports() {
return createExports(this._name, []);
}
}
_a = toReferencePath;
function createExports(name, pathParts) {
const handler = {
get(_, prop) {
if (typeof prop === "string") {
const newParts = [...pathParts, prop];
return createExports(name, newParts);
} else if (prop === toReferencePath) {
let reference = `_reference/childComponent/${name}`;
for (const part of pathParts) {
reference += `/${part}`;
}
return reference;
} else {
return void 0;
}
}
};
return new Proxy({}, handler);
}
function install(definition, options = {}) {
const importedComponentDefinition = definition;
if (typeof importedComponentDefinition.componentDefinitionPath !== "string") {
throw new Error(
"Component definition does not have the required componentDefinitionPath property. This code only works in Convex runtime."
);
}
const name = options.name || importedComponentDefinition.componentDefinitionPath.split("/").pop();
this._childComponents.push([
name,
importedComponentDefinition,
options.args ?? {}
]);
return new InstalledComponent(definition, name);
}
function installWithInit(definition, options) {
const importedComponentDefinition = definition;
if (typeof importedComponentDefinition.componentDefinitionPath !== "string") {
throw new Error(
"Component definition does not have the required componentDefinitionPath property. This code only works in Convex runtime."
);
}
const name = options.name || importedComponentDefinition.componentDefinitionPath.split("/").pop();
this._childComponents.push([name, importedComponentDefinition, null]);
this._onInitCallbacks[name] = (s) => invokeOnInit(s, options.onInit);
return new InstalledComponent(definition, name);
}
function invokeOnInit(argsStr, onInit) {
const argsJson = JSON.parse(argsStr);
const args = (0, import_values.jsonToConvex)(argsJson);
const result = onInit({}, args);
return JSON.stringify((0, import_values.convexToJson)(result));
}
function mount(exports) {
function visit(definition, path, value) {
const valueReference = value[toReferencePath];
if (valueReference) {
if (!path.length) {
throw new Error("Empty export path");
}
let current = definition._exportTree;
for (const part of path.slice(0, -1)) {
let next = current[part];
if (typeof next === "string") {
throw new Error(
`Mount path ${path.join(".")} collides with existing export`
);
}
if (!next) {
next = {};
current[part] = next;
}
current = next;
}
const last = path[path.length - 1];
if (current[last]) {
throw new Error(
`Mount path ${path.join(".")} collides with existing export`
);
}
current[last] = valueReference;
} else {
for (const [key, child] of Object.entries(value)) {
visit(definition, [...path, key], child);
}
}
}
if (exports[toReferencePath]) {
throw new Error(`Cannot mount another component's exports at the root`);
}
visit(this, [], exports);
}
function mountHttp(pathPrefix, component) {
if (!pathPrefix.startsWith("/")) {
throw new Error(`Path prefix '${pathPrefix}' does not start with a /`);
}
if (!pathPrefix.endsWith("/")) {
throw new Error(`Path prefix '${pathPrefix}' must end with a /`);
}
if (this._httpMounts[pathPrefix]) {
throw new Error(`Path '${pathPrefix}' is already mounted.`);
}
const path = extractReferencePath(component);
if (!path) {
throw new Error("`mountHttp` must be called with an `InstalledComponent`.");
}
this._httpMounts[pathPrefix] = path;
}
function exportAppForAnalysis() {
const definitionType = { type: "app" };
const childComponents = serializeChildComponents(this._childComponents);
return {
definitionType,
childComponents,
httpMounts: this._httpMounts,
exports: serializeExportTree(this._exportTree)
};
}
function serializeExportTree(tree) {
const branch = [];
for (const [key, child] of Object.entries(tree)) {
let node;
if (typeof child === "string") {
node = { type: "leaf", leaf: child };
} else {
node = serializeExportTree(child);
}
branch.push([key, node]);
}
return { type: "branch", branch };
}
function serializeChildComponents(childComponents) {
return childComponents.map(([name, definition, p]) => {
let args = null;
if (p !== null) {
args = [];
for (const [name2, value] of Object.entries(p)) {
if (value !== void 0) {
args.push([
name2,
{ type: "value", value: JSON.stringify((0, import_values.convexToJson)(value)) }
]);
}
}
}
const path = definition.componentDefinitionPath;
if (!path)
throw new Error(
"no .componentPath for component definition " + JSON.stringify(definition, null, 2)
);
return {
name,
path,
args
};
});
}
function exportComponentForAnalysis() {
const args = Object.entries(
this._args
).map(([name, validator]) => [
name,
{
type: "value",
value: JSON.stringify(validator.json)
}
]);
const definitionType = {
type: "childComponent",
name: this._name,
args
};
const childComponents = serializeChildComponents(this._childComponents);
return {
name: this._name,
definitionType,
childComponents,
httpMounts: this._httpMounts,
exports: serializeExportTree(this._exportTree)
};
}
function defineComponent(name, options = {}) {
const ret = {
_isRoot: false,
_name: name,
_args: options.args || {},
_childComponents: [],
_httpMounts: {},
_exportTree: {},
_onInitCallbacks: {},
export: exportComponentForAnalysis,
install,
installWithInit,
mount,
mountHttp,
// pretend to conform to ComponentDefinition, which temporarily expects __args
...{}
};
return ret;
}
function defineApp() {
const ret = {
_isRoot: true,
_childComponents: [],
_httpMounts: {},
_exportTree: {},
export: exportAppForAnalysis,
install,
mount,
mountHttp
};
return ret;
}
function currentSystemUdfInComponent(componentId) {
return {
[toReferencePath]: `_reference/currentSystemUdfInComponent/${componentId}`
};
}
function createChildComponents(root, pathParts) {
const handler = {
get(_, prop) {
if (typeof prop === "string") {
const newParts = [...pathParts, prop];
return createChildComponents(root, newParts);
} else if (prop === toReferencePath) {
if (pathParts.length < 1) {
const found = [root, ...pathParts].join(".");
throw new Error(
`API path is expected to be of the form \`${root}.childComponent.functionName\`. Found: \`${found}\``
);
}
return `_reference/childComponent/` + pathParts.join("/");
} else {
return void 0;
}
}
};
return new Proxy({}, handler);
}
function createComponentArg() {
return (ctx, name) => {
const result = (0, import_syscall.performSyscall)("1.0/componentArgument", {
name
});
return (0, import_values.jsonToConvex)(result).value;
};
}
const componentsGeneric = () => createChildComponents("components", []);
//# sourceMappingURL=index.js.map