From 2043d1ed922dd13380b1d0e1ca4b1c94c7f5f229 Mon Sep 17 00:00:00 2001 From: karthik2804 Date: Mon, 3 Jun 2024 17:52:26 +0200 Subject: [PATCH 1/7] update SDK to use fetchEvent Signed-off-by: karthik2804 --- lib/inboundHttp.d.ts | 19 + lib/inboundHttp.js | 110 +++++ lib/inboundRedis.d.ts | 3 + lib/inboundRedis.js | 2 + lib/index.d.ts | 12 + lib/index.js | 12 + lib/keyValue.d.ts | 11 + lib/keyValue.js | 42 ++ lib/llm.d.ts | 40 ++ lib/llm.js | 26 ++ lib/mqtt.d.ts | 9 + lib/mqtt.js | 11 + lib/mysql.d.ts | 6 + lib/mysql.js | 31 ++ lib/postgres.d.ts | 6 + lib/postgres.js | 31 ++ lib/rdbmsHelper.d.ts | 2 + lib/rdbmsHelper.js | 39 ++ lib/redis.d.ts | 15 + lib/redis.js | 5 + lib/router.d.ts | 56 +++ lib/router.js | 49 +++ lib/sqlite.d.ts | 32 ++ lib/sqlite.js | 77 ++++ lib/types/rdbms.d.ts | 108 +++++ lib/types/wasi-http.d.ts | 136 ++++++ lib/variables.d.ts | 1 + lib/variables.js | 10 + package-lock.json | 544 +++++++++++++++++++++++- package.json | 2 +- src/inboundHttp.ts | 185 ++------ src/index.ts | 4 +- src/router.ts | 15 +- templates/http-ts/content/package.json | 6 +- templates/http-ts/content/src/index.ts | 10 +- templates/http-ts/content/src/spin.ts | 30 +- templates/http-ts/content/tsconfig.json | 3 +- tsconfig.json | 1 + 38 files changed, 1519 insertions(+), 182 deletions(-) create mode 100644 lib/inboundHttp.d.ts create mode 100644 lib/inboundHttp.js create mode 100644 lib/inboundRedis.d.ts create mode 100644 lib/inboundRedis.js create mode 100644 lib/index.d.ts create mode 100644 lib/index.js create mode 100644 lib/keyValue.d.ts create mode 100644 lib/keyValue.js create mode 100644 lib/llm.d.ts create mode 100644 lib/llm.js create mode 100644 lib/mqtt.d.ts create mode 100644 lib/mqtt.js create mode 100644 lib/mysql.d.ts create mode 100644 lib/mysql.js create mode 100644 lib/postgres.d.ts create mode 100644 lib/postgres.js create mode 100644 lib/rdbmsHelper.d.ts create mode 100644 lib/rdbmsHelper.js create mode 100644 lib/redis.d.ts create mode 100644 lib/redis.js create mode 100644 lib/router.d.ts create mode 100644 lib/router.js create mode 100644 lib/sqlite.d.ts create mode 100644 lib/sqlite.js create mode 100644 lib/types/rdbms.d.ts create mode 100644 lib/types/wasi-http.d.ts create mode 100644 lib/variables.d.ts create mode 100644 lib/variables.js diff --git a/lib/inboundHttp.d.ts b/lib/inboundHttp.d.ts new file mode 100644 index 00000000..d5e114e6 --- /dev/null +++ b/lib/inboundHttp.d.ts @@ -0,0 +1,19 @@ +type ResolveFunction = (value: Response | PromiseLike) => void; +export declare class ResponseBuilder { + headers: Headers; + statusCode: number; + private hasWrittenHeaders; + private hasSentResponse; + private resolveFunction; + private streamController; + constructor(resolve: ResolveFunction); + status(code: number): ResponseBuilder; + getStatus(): number; + set(arg1: string | { + [key: string]: string; + }, arg2?: string): ResponseBuilder; + send(value?: BodyInit): void; + write(value: BodyInit): void; + end(): void; +} +export {}; diff --git a/lib/inboundHttp.js b/lib/inboundHttp.js new file mode 100644 index 00000000..cef07e79 --- /dev/null +++ b/lib/inboundHttp.js @@ -0,0 +1,110 @@ +export class ResponseBuilder { + constructor(resolve) { + this.headers = new Headers(); + this.statusCode = 200; + this.hasWrittenHeaders = false; + this.hasSentResponse = false; + this.resolveFunction = resolve; + } + status(code) { + if (this.hasWrittenHeaders) { + throw new Error('Headers and Status already sent'); + } + this.statusCode = code; + return this; + } + getStatus() { + return this.statusCode; + } + set(arg1, arg2) { + if (this.hasWrittenHeaders) { + throw new Error('Headers already sent'); + } + if (typeof arg1 === 'string' && typeof arg2 === 'string') { + this.headers.set(arg1, arg2); + } + else if (typeof arg1 === 'object' && arg2 === undefined) { + for (const key in arg1) { + this.headers.set(key, arg1[key]); + } + } + else { + throw new Error('Invalid arguments'); + } + return this; + } + send(value = new Uint8Array()) { + if (this.hasSentResponse) { + throw new Error('Response has already been sent'); + } + if (!this.hasWrittenHeaders) { + this.resolveFunction(new Response(value, { headers: this.headers, status: this.statusCode })); + this.hasWrittenHeaders = true; + } + else { + this.write(value); + } + this.end(); + this.hasSentResponse = true; + } + write(value) { + if (this.hasSentResponse) { + throw new Error('Response has already been sent'); + } + if (!this.hasWrittenHeaders) { + let temp; + let readableStream = new ReadableStream({ + start(controller) { + controller.enqueue(convertToUint8Array(value)); + let streamController = { + pump: (value) => { + controller.enqueue(convertToUint8Array(value)); + }, + close: () => { + controller.close(); + }, + }; + temp = streamController; + }, + }); + this.streamController = temp; + this.resolveFunction(new Response(readableStream, { + headers: this.headers, + status: this.statusCode, + })); + this.hasWrittenHeaders = true; + return; + } + this.streamController.pump(convertToUint8Array(value)); + } + end() { + if (this.hasSentResponse) { + throw new Error('Response has already been sent'); + } + // close stream + this.streamController.close(); + this.hasSentResponse = true; + } +} +function convertToUint8Array(body) { + if (body instanceof ArrayBuffer) { + return new Uint8Array(body); + } + else if (ArrayBuffer.isView(body)) { + return new Uint8Array(body.buffer, body.byteOffset, body.byteLength); + } + else if (typeof body === 'string') { + const encoder = new TextEncoder(); + const utf8Array = encoder.encode(body); + return utf8Array; + } + else if (body instanceof URLSearchParams) { + const encoder = new TextEncoder(); + const bodyString = body.toString(); + const utf8Array = encoder.encode(bodyString); + return utf8Array; + } + else { + throw new Error('Unsupported body type'); + } +} diff --git a/lib/inboundRedis.d.ts b/lib/inboundRedis.d.ts new file mode 100644 index 00000000..998a50cf --- /dev/null +++ b/lib/inboundRedis.d.ts @@ -0,0 +1,3 @@ +export declare abstract class RedisHandler { + abstract handleMessage(msg: Uint8Array): Promise; +} diff --git a/lib/inboundRedis.js b/lib/inboundRedis.js new file mode 100644 index 00000000..a906b085 --- /dev/null +++ b/lib/inboundRedis.js @@ -0,0 +1,2 @@ +export class RedisHandler { +} diff --git a/lib/index.d.ts b/lib/index.d.ts new file mode 100644 index 00000000..2b2b07b6 --- /dev/null +++ b/lib/index.d.ts @@ -0,0 +1,12 @@ +import { ResponseBuilder } from './inboundHttp'; +import { RedisHandler } from './inboundRedis'; +import * as Llm from './llm'; +import * as Variables from './variables'; +import * as Redis from './redis'; +import * as Kv from './keyValue'; +import * as Sqlite from './sqlite'; +import * as Postgres from './postgres'; +import * as Mysql from './mysql'; +import * as Mqtt from './mqtt'; +import { Router } from './router'; +export { Router, Llm, Variables, Redis, Kv, Sqlite, Postgres, Mysql, Mqtt, RedisHandler, ResponseBuilder, }; diff --git a/lib/index.js b/lib/index.js new file mode 100644 index 00000000..2b2b07b6 --- /dev/null +++ b/lib/index.js @@ -0,0 +1,12 @@ +import { ResponseBuilder } from './inboundHttp'; +import { RedisHandler } from './inboundRedis'; +import * as Llm from './llm'; +import * as Variables from './variables'; +import * as Redis from './redis'; +import * as Kv from './keyValue'; +import * as Sqlite from './sqlite'; +import * as Postgres from './postgres'; +import * as Mysql from './mysql'; +import * as Mqtt from './mqtt'; +import { Router } from './router'; +export { Router, Llm, Variables, Redis, Kv, Sqlite, Postgres, Mysql, Mqtt, RedisHandler, ResponseBuilder, }; diff --git a/lib/keyValue.d.ts b/lib/keyValue.d.ts new file mode 100644 index 00000000..2d78cef8 --- /dev/null +++ b/lib/keyValue.d.ts @@ -0,0 +1,11 @@ +export interface Store { + get: (key: string) => Uint8Array | null; + set: (key: string, value: Uint8Array | string | object) => void; + delete: (key: string) => void; + exists: (key: string) => boolean; + getKeys: () => string[]; + getJson: (key: string) => any; + setJson: (key: string, value: any) => void; +} +export declare function open(label: string): Store; +export declare function openDefault(): Store; diff --git a/lib/keyValue.js b/lib/keyValue.js new file mode 100644 index 00000000..26017c03 --- /dev/null +++ b/lib/keyValue.js @@ -0,0 +1,42 @@ +//@ts-ignore +import * as spinKv from 'fermyon:spin/key-value@2.0.0'; +const encoder = new TextEncoder(); +const decoder = new TextDecoder(); +function createKvStore(store) { + let kv = { + get: (key) => { + return store.get(key); + }, + set: (key, value) => { + if (typeof value === 'string') { + value = encoder.encode(value); + } + else if (typeof value === 'object') { + value = encoder.encode(JSON.stringify(value)); + } + store.set(key, value); + }, + delete: (key) => { + store.delete(key); + }, + exists: (key) => { + return store.exists(key); + }, + getKeys: () => { + return store.getKeys(); + }, + getJson: (key) => { + return JSON.parse(decoder.decode(store.get(key) || new Uint8Array())); + }, + setJson: (key, value) => { + store.set(key, encoder.encode(JSON.stringify(value))); + }, + }; + return kv; +} +export function open(label) { + return createKvStore(spinKv.Store.open(label)); +} +export function openDefault() { + return createKvStore(spinKv.Store.open('default')); +} diff --git a/lib/llm.d.ts b/lib/llm.d.ts new file mode 100644 index 00000000..4fc01e70 --- /dev/null +++ b/lib/llm.d.ts @@ -0,0 +1,40 @@ +export declare enum InferencingModels { + Llama2Chat = "llama2-chat", + CodellamaInstruct = "codellama-instruct" +} +export declare enum EmbeddingModels { + AllMiniLmL6V2 = "all-minilm-l6-v2" +} +export interface InferencingOptions { + maxTokens?: number; + repeatPenalty?: number; + repeatPenaltyLastNTokenCount?: number; + temperature?: number; + topK?: number; + topP?: number; +} +export interface InternalInferencingOptions { + maxTokens?: number; + repeatPenalty?: number; + repeatPenaltyLastNTokenCount?: number; + temperature?: number; + topK?: number; + topP?: number; +} +export interface InferenceUsage { + promptTokenCount: number; + generatedTokenCount: number; +} +export interface InferenceResult { + text: string; + usage: InferenceUsage; +} +export interface EmbeddingUsage { + promptTokenCount: number; +} +export interface EmbeddingResult { + embeddings: Array>; + usage: EmbeddingUsage; +} +export declare function infer(model: InferencingModels | string, prompt: string, options?: InferencingOptions): InferenceResult; +export declare const generateEmbeddings: (model: EmbeddingModels | string, text: Array) => EmbeddingResult; diff --git a/lib/llm.js b/lib/llm.js new file mode 100644 index 00000000..824d28c6 --- /dev/null +++ b/lib/llm.js @@ -0,0 +1,26 @@ +import { infer as llmInfer, generateEmbeddings as llmGenerateEmbeddings, +//@ts-ignore + } from 'fermyon:spin/llm@2.0.0'; +export var InferencingModels; +(function (InferencingModels) { + InferencingModels["Llama2Chat"] = "llama2-chat"; + InferencingModels["CodellamaInstruct"] = "codellama-instruct"; +})(InferencingModels || (InferencingModels = {})); +export var EmbeddingModels; +(function (EmbeddingModels) { + EmbeddingModels["AllMiniLmL6V2"] = "all-minilm-l6-v2"; +})(EmbeddingModels || (EmbeddingModels = {})); +export function infer(model, prompt, options) { + let inference_options = { + maxTokens: options?.maxTokens || 100, + repeatPenalty: options?.repeatPenalty || 1.1, + repeatPenaltyLastNTokenCount: options?.repeatPenaltyLastNTokenCount || 64, + temperature: options?.temperature || 0.8, + topK: options?.topK || 40, + topP: options?.topP || 0.9, + }; + return llmInfer(model, prompt, inference_options); +} +export const generateEmbeddings = (model, text) => { + return llmGenerateEmbeddings(model, text); +}; diff --git a/lib/mqtt.d.ts b/lib/mqtt.d.ts new file mode 100644 index 00000000..ad6605b2 --- /dev/null +++ b/lib/mqtt.d.ts @@ -0,0 +1,9 @@ +export declare enum QoS { + AtMostOnce = "at-most-once", + AtLeastOnce = "at-least-once", + ExactlyOnce = "exactly-once" +} +export interface MqttConnection { + publish: (topic: string, payload: Uint8Array, qos: QoS) => void; +} +export declare function open(address: string, username: string, password: string, keepAliveIntervalInSecs: number): MqttConnection; diff --git a/lib/mqtt.js b/lib/mqtt.js new file mode 100644 index 00000000..19363e11 --- /dev/null +++ b/lib/mqtt.js @@ -0,0 +1,11 @@ +//@ts-ignore +import * as spinMqtt from 'fermyon:spin/mqtt@2.0.0'; +export var QoS; +(function (QoS) { + QoS["AtMostOnce"] = "at-most-once"; + QoS["AtLeastOnce"] = "at-least-once"; + QoS["ExactlyOnce"] = "exactly-once"; +})(QoS || (QoS = {})); +export function open(address, username, password, keepAliveIntervalInSecs) { + return spinMqtt.Connection.open(address, username, password, keepAliveIntervalInSecs); +} diff --git a/lib/mysql.d.ts b/lib/mysql.d.ts new file mode 100644 index 00000000..8969a27f --- /dev/null +++ b/lib/mysql.d.ts @@ -0,0 +1,6 @@ +import { RdbmsParameterValue, RdbmsRowSet } from './types/rdbms'; +export interface MysqlConnection { + query: (statement: string, params: RdbmsParameterValue[]) => RdbmsRowSet; + execute: (statement: string, params: RdbmsParameterValue[]) => number; +} +export declare function open(address: string): MysqlConnection; diff --git a/lib/mysql.js b/lib/mysql.js new file mode 100644 index 00000000..cc1dd2f9 --- /dev/null +++ b/lib/mysql.js @@ -0,0 +1,31 @@ +//@ts-ignore +import * as spinMysql from 'fermyon:spin/mysql@2.0.0'; +import { convertRdbmsToWitTypes } from './rdbmsHelper'; +function createMysqlConnection(connection) { + return { + query: (statement, params) => { + let santizedParams = convertRdbmsToWitTypes(params); + let ret = connection.query(statement, santizedParams); + let results = { + columns: ret.columns, + rows: [], + }; + ret.rows.map((k, rowIndex) => { + results.rows.push({}); + k.map((val, valIndex) => { + results.rows[rowIndex][results.columns[valIndex].name] = + val.tag == 'db-null' || val.tag == 'unsupported' ? null : val.val; + }); + }); + return results; + }, + execute: (statement, params) => { + let santizedParams = convertRdbmsToWitTypes(params); + let ret = connection.execute(statement, santizedParams); + return ret; + }, + }; +} +export function open(address) { + return createMysqlConnection(spinMysql.Connection.open(address)); +} diff --git a/lib/postgres.d.ts b/lib/postgres.d.ts new file mode 100644 index 00000000..1ab9bee5 --- /dev/null +++ b/lib/postgres.d.ts @@ -0,0 +1,6 @@ +import { RdbmsParameterValue, RdbmsRowSet } from './types/rdbms'; +export interface PostgresConnection { + query: (statement: string, params: RdbmsParameterValue[]) => RdbmsRowSet; + execute: (statement: string, params: RdbmsParameterValue[]) => number; +} +export declare function open(address: string): PostgresConnection; diff --git a/lib/postgres.js b/lib/postgres.js new file mode 100644 index 00000000..71a743fb --- /dev/null +++ b/lib/postgres.js @@ -0,0 +1,31 @@ +//@ts-ignore +import * as spinPg from 'fermyon:spin/postgres@2.0.0'; +import { convertRdbmsToWitTypes } from './rdbmsHelper'; +function createPostgresConnection(connection) { + return { + query: (statement, params) => { + let santizedParams = convertRdbmsToWitTypes(params); + let ret = connection.query(statement, santizedParams); + let results = { + columns: ret.columns, + rows: [], + }; + ret.rows.map((k, rowIndex) => { + results.rows.push({}); + k.map((val, valIndex) => { + results.rows[rowIndex][results.columns[valIndex].name] = + val.tag == 'db-null' || val.tag == 'unsupported' ? null : val.val; + }); + }); + return results; + }, + execute: (statement, params) => { + let santizedParams = convertRdbmsToWitTypes(params); + let ret = connection.execute(statement, santizedParams); + return ret; + }, + }; +} +export function open(address) { + return createPostgresConnection(spinPg.Connection.open(address)); +} diff --git a/lib/rdbmsHelper.d.ts b/lib/rdbmsHelper.d.ts new file mode 100644 index 00000000..e4b5c50a --- /dev/null +++ b/lib/rdbmsHelper.d.ts @@ -0,0 +1,2 @@ +import { RdbmsParameterValue, SpinRdbmsParameterValue } from './types/rdbms'; +export declare function convertRdbmsToWitTypes(parameters: RdbmsParameterValue[]): SpinRdbmsParameterValue[]; diff --git a/lib/rdbmsHelper.js b/lib/rdbmsHelper.js new file mode 100644 index 00000000..6a088775 --- /dev/null +++ b/lib/rdbmsHelper.js @@ -0,0 +1,39 @@ +export function convertRdbmsToWitTypes(parameters) { + let sanitized = []; + for (let k of parameters) { + if (typeof k === 'object') { + sanitized.push(k); + continue; + } + if (typeof k === 'string') { + sanitized.push({ tag: 'str', val: k }); + continue; + } + if (typeof k === null) { + sanitized.push({ tag: 'db-null' }); + continue; + } + if (typeof k === 'boolean') { + sanitized.push({ tag: 'boolean', val: k }); + continue; + } + if (typeof k === 'bigint') { + sanitized.push({ tag: 'int64', val: k }); + continue; + } + if (typeof k === 'number') { + isFloat(k) + ? sanitized.push({ tag: 'floating64', val: k }) + : sanitized.push({ tag: 'int32', val: k }); + continue; + } + if (k instanceof Uint8Array) { + sanitized.push({ tag: 'binary', val: k }); + continue; + } + } + return sanitized; +} +function isFloat(number) { + return number % 1 !== 0; +} diff --git a/lib/redis.d.ts b/lib/redis.d.ts new file mode 100644 index 00000000..9dc93449 --- /dev/null +++ b/lib/redis.d.ts @@ -0,0 +1,15 @@ +export type payload = Uint8Array; +export type redisParameter = number | Uint8Array; +export type redisResult = number | Uint8Array | null | string; +export interface RedisConnection { + publish: (channel: string, payload: payload) => void; + get: (key: string) => payload | null; + set: (key: string, value: payload) => void; + incr: (key: string) => number; + del: (key: string) => number; + sadd: (key: string, value: string[]) => number; + smembers: (key: string) => string[]; + srem: (key: string, value: string[]) => number; + execute: (command: string, args: redisParameter[]) => redisResult[]; +} +export declare function open(address: string): RedisConnection; diff --git a/lib/redis.js b/lib/redis.js new file mode 100644 index 00000000..b938482a --- /dev/null +++ b/lib/redis.js @@ -0,0 +1,5 @@ +//@ts-ignore +import * as spinRedis from 'fermyon:spin/redis@2.0.0'; +export function open(address) { + return spinRedis.Connection.open(address); +} diff --git a/lib/router.d.ts b/lib/router.d.ts new file mode 100644 index 00000000..1594e225 --- /dev/null +++ b/lib/router.d.ts @@ -0,0 +1,56 @@ +import { ResponseBuilder } from './inboundHttp'; +declare type GenericTraps = { + [key: string]: any; +}; +export declare type RequestLike = { + method: string; + url: string; +} & GenericTraps; +declare type IRequest = { + method: string; + url: string; + params: { + [key: string]: string; + }; + query: { + [key: string]: string | string[] | undefined; + }; + proxy?: any; +} & GenericTraps; +interface RouteHandler { + (request: IRequest, ...args: any): any; +} +interface SpinRouteHandler { + (metadata: IRequest, req: Request, res: ResponseBuilder, ...args: any): any; +} +declare type RouteEntry = [string, RegExp, RouteHandler[]]; +declare type Route = (path: string, ...handlers: RouteHandler[]) => T; +declare type RouterHints = { + all: Route; + delete: Route; + get: Route; + options: Route; + patch: Route; + post: Route; + put: Route; +}; +declare type RouterType = { + __proto__: RouterType; + routes: RouteEntry[]; + handle: (request: RequestLike, ...extra: any) => Promise; +} & RouterHints; +interface routerType { + all(path: string, ...handlers: SpinRouteHandler[]): RouterType; + delete(path: string, ...handlers: SpinRouteHandler[]): RouterType; + get(path: string, ...handlers: SpinRouteHandler[]): RouterType; + handle(request: RequestLike, ...extras: any): Promise; + handleRequest(request: Request, response: ResponseBuilder, ...extras: any): Promise; + options(path: string, ...handlers: SpinRouteHandler[]): RouterType; + patch(path: string, ...handlers: SpinRouteHandler[]): RouterType; + post(path: string, ...handlers: SpinRouteHandler[]): RouterType; + put(path: string, ...handlers: SpinRouteHandler[]): RouterType; + routes: RouteEntry[]; +} +/** @internal */ +declare function Router(): routerType; +export { Router, routerType }; diff --git a/lib/router.js b/lib/router.js new file mode 100644 index 00000000..ec0bf197 --- /dev/null +++ b/lib/router.js @@ -0,0 +1,49 @@ +import { Router as _router } from 'itty-router'; +/** @internal */ +function Router() { + let _spinRouter = _router(); + return { + all: function (path, ...handlers) { + return _spinRouter.all(path, ...wrapRouteHandler(handlers)); + }, + delete: function (path, ...handlers) { + return _spinRouter.delete(path, ...wrapRouteHandler(handlers)); + }, + get: function (path, ...handlers) { + return _spinRouter.get(path, ...wrapRouteHandler(handlers)); + }, + handle: function (request, ...extra) { + return _spinRouter.handle(request, ...extra); + }, + handleRequest: function (request, response, ...a) { + return _spinRouter.handle({ + method: request.method, + url: request.headers.get('spin-full-url') || '', + }, request, response, ...a); + }, + options: function (path, ...handlers) { + return _spinRouter.options(path, ...wrapRouteHandler(handlers)); + }, + patch: function (path, ...handlers) { + return _spinRouter.patch(path, ...wrapRouteHandler(handlers)); + }, + post: function (path, ...handlers) { + return _spinRouter.post(path, ...wrapRouteHandler(handlers)); + }, + put: function (path, ...handlers) { + return _spinRouter.put(path, ...wrapRouteHandler(handlers)); + }, + routes: _spinRouter.routes, + }; +} +function wrapRouteHandler(handlers) { + let h = []; + for (let handler of handlers) { + let fn = async (metadata, req, res, ...args) => { + return handler(metadata, req, res, args); + }; + h.push(fn); + } + return h; +} +export { Router }; diff --git a/lib/sqlite.d.ts b/lib/sqlite.d.ts new file mode 100644 index 00000000..2ca863f9 --- /dev/null +++ b/lib/sqlite.d.ts @@ -0,0 +1,32 @@ +export type sqliteValues = ValueInteger | ValueReal | ValueText | ValueBlob | ValueNull; +export type ParameterValue = sqliteValues | number | bigint | null | string | Uint8Array; +export type ValueInteger = { + tag: 'integer'; + val: number | bigint; +}; +export type ValueReal = { + tag: 'real'; + val: number | bigint; +}; +export type ValueText = { + tag: 'text'; + val: string; +}; +export type ValueBlob = { + tag: 'blob'; + val: Uint8Array; +}; +export type ValueNull = { + tag: 'null'; +}; +export interface SqliteResult { + columns: string[]; + rows: { + [key: string]: number | bigint | null | string | Uint8Array; + }[]; +} +export interface SqliteConnection { + execute: (statement: string, parameters: ParameterValue[]) => SqliteResult; +} +export declare function open(label: string): SqliteConnection; +export declare function openDefault(): SqliteConnection; diff --git a/lib/sqlite.js b/lib/sqlite.js new file mode 100644 index 00000000..fe698729 --- /dev/null +++ b/lib/sqlite.js @@ -0,0 +1,77 @@ +//@ts-ignore +import * as spinSqlite from 'fermyon:spin/sqlite@2.0.0'; +function createSqliteConnection(connection) { + return { + execute: (statement, parameters) => { + let santizedParams = convertToWitTypes(parameters); + let ret = connection.execute(statement, santizedParams); + let results = { + columns: ret.columns, + rows: [], + }; + ret.rows.map((k, rowIndex) => { + results.rows.push({}); + k.values.map((val, valIndex) => { + results.rows[rowIndex][results.columns[valIndex]] = val.val; + }); + }); + return results; + }, + }; +} +export function open(label) { + return createSqliteConnection(spinSqlite.Connection.open(label)); +} +export function openDefault() { + return createSqliteConnection(spinSqlite.Connection.open('default')); +} +const valueInteger = (value) => { + return { tag: 'integer', val: value }; +}; +const valueReal = (value) => { + return { tag: 'real', val: value }; +}; +const valueText = (value) => { + return { tag: 'text', val: value }; +}; +const valueBlob = (value) => { + return { tag: 'blob', val: value }; +}; +const valueNull = () => { + return { tag: 'null' }; +}; +function convertToWitTypes(parameters) { + let sanitized = []; + for (let k of parameters) { + if (typeof k === 'object') { + sanitized.push(k); + continue; + } + if (typeof k === 'number') { + isFloat(k) + ? sanitized.push(valueReal(k)) + : sanitized.push(valueInteger(k)); + continue; + } + if (typeof k === 'bigint') { + sanitized.push(valueInteger(k)); + continue; + } + if (typeof k === 'string') { + sanitized.push(valueText(k)); + continue; + } + if (k === null) { + sanitized.push(valueNull()); + continue; + } + if (k instanceof Uint8Array) { + sanitized.push(valueBlob(k)); + continue; + } + } + return sanitized; +} +function isFloat(number) { + return number % 1 !== 0; +} diff --git a/lib/types/rdbms.d.ts b/lib/types/rdbms.d.ts new file mode 100644 index 00000000..2f4b5ea5 --- /dev/null +++ b/lib/types/rdbms.d.ts @@ -0,0 +1,108 @@ +export type RdbmsValueBoolean = { tag: 'boolean'; val: boolean }; +export type RdbmsValueInt8 = { tag: 'int8'; val: number }; +export type RdbmsValueInt16 = { tag: 'int16'; val: number }; +export type RdbmsValueInt32 = { tag: 'int32'; val: number }; +export type RdbmsValueInt64 = { tag: 'int64'; val: bigint }; +export type RdbmsValueUint8 = { tag: 'uint8'; val: number }; +export type RdbmsValueUint16 = { tag: 'uint16'; val: number }; +export type RdbmsValueUint32 = { tag: 'uint32'; val: number }; +export type RdbmsValueUint64 = { tag: 'uint64'; val: bigint }; +export type RdbmsValueFloating32 = { tag: 'floating32'; val: number }; +export type RdbmsValueFloating64 = { tag: 'floating64'; val: number }; +export type RdbmsValueStr = { tag: 'str'; val: string }; +export type RdbmsValueBinary = { tag: 'binary'; val: Uint8Array }; +export type RdbmsValueDbNull = { tag: 'db-null' }; + +export type SpinRdbmsParameterValue = + | RdbmsValueBoolean + | RdbmsValueInt8 + | RdbmsValueInt16 + | RdbmsValueInt32 + | RdbmsValueInt64 + | RdbmsValueUint8 + | RdbmsValueUint16 + | RdbmsValueUint32 + | RdbmsValueUint64 + | RdbmsValueFloating32 + | RdbmsValueFloating64 + | RdbmsValueStr + | RdbmsValueBinary + | RdbmsValueDbNull; + +export type RdbmsParameterValue = + | SpinRdbmsParameterValue + | number + | bigint + | boolean + | null + | Uint8Array + | string; + +export interface RdbmsColumn { + name: string; + dataType: RdbmsDataType[]; +} + +export type RdbmsRow = RdbmsDbValue[]; + +export interface SpinRdbmsRowSet { + columns: RdbmsColumn[]; + rows: RdbmsRow[]; +} + +export interface RdbmsRowSet { + columns: RdbmsColumn[]; + rows: { + [key: string]: number | boolean | bigint | null | string | Uint8Array; + }[]; +} + +export type RdbmsDbBoolean = { tag: 'boolean'; val: boolean }; +export type RdbmsDbInt8 = { tag: 'int8'; val: number }; +export type RdbmsDbInt16 = { tag: 'int16'; val: number }; +export type RdbmsDbInt32 = { tag: 'int32'; val: number }; +export type RdbmsDbInt64 = { tag: 'int64'; val: number }; +export type RdbmsDbUint8 = { tag: 'uint8'; val: number }; +export type RdbmsDbUint16 = { tag: 'uint16'; val: number }; +export type RdbmsDbUint32 = { tag: 'uint32'; val: number }; +export type RdbmsDbUint64 = { tag: 'uint64'; val: number }; +export type RdbmsDbFloating32 = { tag: 'floating32'; val: number }; +export type RdbmsDbFloating64 = { tag: 'floating64'; val: number }; +export type RdbmsDbStr = { tag: 'str'; val: string }; +export type RdbmsDbBinary = { tag: 'binary'; val: Uint8Array }; +export type RdbmsDbNull = { tag: 'db-null' }; +export type RdbmsDbUnsupported = { tag: 'unsupported' }; + +export type RdbmsDbValue = + | RdbmsDbBoolean + | RdbmsDbInt8 + | RdbmsDbInt16 + | RdbmsDbInt32 + | RdbmsDbInt64 + | RdbmsDbUint8 + | RdbmsDbUint16 + | RdbmsDbUint32 + | RdbmsDbUint64 + | RdbmsDbFloating32 + | RdbmsDbFloating64 + | RdbmsDbStr + | RdbmsDbBinary + | RdbmsDbNull + | RdbmsDbUnsupported; + +export enum RdbmsDataType { + RdbmsBoolean = 'boolean', + RdbmsInt8 = 'int8', + RdbmsInt16 = 'int16', + RdbmsInt32 = 'int32', + RdbmsInt64 = 'int64', + RdbmsUint8 = 'uint8', + RdbmsUint16 = 'uint16', + RdbmsUint32 = 'uint32', + RdbmsUint64 = 'uint64', + RdbmsFloating32 = 'floating32', + RdbmsFloating64 = 'floating64', + RdbmsStr = 'str', + RdbmsBinary = 'binary', + RdbmsOther = 'other', +} diff --git a/lib/types/wasi-http.d.ts b/lib/types/wasi-http.d.ts new file mode 100644 index 00000000..be4852cb --- /dev/null +++ b/lib/types/wasi-http.d.ts @@ -0,0 +1,136 @@ +export interface method { + tag: + | 'get' + | 'head' + | 'post' + | 'put' + | 'delete' + | 'connect' + | 'options' + | 'trace' + | 'patch' + | { kind: 'other'; value: string }; +} + +export interface schema { + tag: 'HTTP' | 'HTTPS' | { kind: 'other'; value: string }; +} + +export type FieldValue = Uint8Array; +export type FieldKey = string; + +export declare class headers { + constructor(); + static fromList: (entries: [FieldKey, FieldValue][]) => headers; + get: (name: FieldKey) => FieldValue[]; + has: (name: FieldKey) => boolean; + set: (name: FieldKey, value: FieldValue) => void; + delete: (name: FieldKey) => void; + append: (name: FieldKey, value: FieldValue) => void; + entries: () => [FieldKey, FieldValue][]; + clone: () => headers; +} +export type trailers = headers | { tag: 'none' }; + +export interface Pollable { + read: () => boolean; + block: () => void; +} + +export interface InputStream { + read: (len: number) => Uint8Array; + blockingRead: (len: number) => Uint8Array; + skip: (len: number) => Uint8Array; + blockingSkip: (len: number) => Uint8Array; + subscribe: () => Pollable; +} + +export interface FutureTrailers { + subscribe: () => Pollable; + get: () => trailers | null; +} + +export declare class IncomingBody { + stream: () => InputStream; + static finish: (incomingBody: IncomingBody) => FutureTrailers; +} + +export interface OutputStream { + checkWrite: () => bigint; + write: (content: Uint8Array) => void; + blockingWriteAndFlush: (content: Uint8Array) => void; + flush: () => void; + blockingFlush: () => void; + subscribe: () => Pollable; + writeZeros: (len: number) => void; + blockingWriteZerosAndFlush: (len: number) => void; + splice: (src: InputStream, len: number) => number; + blockingSplice: (src: InputStream, len: number) => number; + [Symbol.dispose](): void; +} + +export declare class OutgoingBody { + write: () => OutputStream; + static finish: ( + outgoingBody: OutgoingBody, + trailers: trailers | null, + ) => void; +} + +export interface IncomingRequest { + method: () => method; + + /// Returns the path with query parameters from the request, as a string. + pathWithQuery: () => string | null; + + /// Returns the protocol scheme from the request. + scheme: () => scheme; + + /// Returns the authority from the request, if it was present. + authority: () => string; + + /// Get the `headers` associated with the request. + /// + /// The returned `headers` resource is immutable: `set`, `append`, and + /// `delete` operations will fail with `header-error.immutable`. + /// + /// The `headers` returned are a child resource: it must be dropped before + /// the parent `incoming-request` is dropped. Dropping this + /// `incoming-request` before all children are dropped will trap. + headers: () => headers; + + /// Gives the `incoming-body` associated with this request. Will only + /// return success at most once, and subsequent calls will return error. + consume: () => IncomingBody; +} + +export declare class OutgoingResponse { + constructor(headers: headers); + /// Get the HTTP Status Code for the Response. + statusCode: () => number; + + /// Set the HTTP Status Code for the Response. Fails if the status-code + /// given is not a valid http status code. + setStatusCode: (statusCode: number) => void; + + /// Get the headers associated with the Request. + /// + /// The returned `headers` resource is immutable: `set`, `append`, and + /// `delete` operations will fail with `header-error.immutable`. + /// + /// This headers resource is a child: it must be dropped before the parent + /// `outgoing-request` is dropped, or its ownership is transfered to + /// another component by e.g. `outgoing-handler.handle`. + headers: () => headers; + + /// Returns the resource corresponding to the outgoing Body for this Response. + /// + /// Returns success on the first call: the `outgoing-body` resource for + /// this `outgoing-response` can be retrieved at most once. Subsequent + /// calls will return error. + body: () => OutgoingBody; +} + +export declare class ResponseOutparam { + static set: (param: ResponseOutparam, response: OutgoingResponse) => void; +} diff --git a/lib/variables.d.ts b/lib/variables.d.ts new file mode 100644 index 00000000..cb1928a1 --- /dev/null +++ b/lib/variables.d.ts @@ -0,0 +1 @@ +export declare function get(key: string): string | null; diff --git a/lib/variables.js b/lib/variables.js new file mode 100644 index 00000000..35699e1d --- /dev/null +++ b/lib/variables.js @@ -0,0 +1,10 @@ +//@ts-ignore +import { get as spinGet } from 'fermyon:spin/variables@2.0.0'; +export function get(key) { + try { + return spinGet(key); + } + catch (e) { + return null; + } +} diff --git a/package-lock.json b/package-lock.json index 1e4b8920..ba2c3ce5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7,9 +7,9 @@ "": { "name": "@fermyon/spin-sdk", "version": "2.0.0-alpha.1", - "license": "ISC", + "license": "Apache-2.0", "dependencies": { - "@bytecodealliance/componentize-js": "^0.8.3", + "@bytecodealliance/componentize-js": "https://github.com/fermyon/ComponentizeJS#use_fetch_event", "itty-router": "^3.0.12", "yargs": "^17.7.2" }, @@ -21,9 +21,9 @@ "typescript": "^5.4.3" } }, - "../../../adobe/aio-experiments/ComponentizeJS": { - "name": "@bytecodealliance/componentize-js", + "node_modules/@bytecodealliance/componentize-js": { "version": "0.8.3", + "resolved": "git+ssh://git@github.com/fermyon/ComponentizeJS.git#48f77659eedcd8c38200f0368cc61428328aa390", "workspaces": [ "." ], @@ -31,15 +31,204 @@ "@bytecodealliance/jco": "1.1.1", "@bytecodealliance/wizer": "^3.0.1", "es-module-lexer": "^1.4.1" - }, - "devDependencies": { + } + }, + "node_modules/@bytecodealliance/jco": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@bytecodealliance/jco/-/jco-1.1.1.tgz", + "integrity": "sha512-s8Zz6GFPlo2g+dsGp1OMIWXSZnM4FyIloxNAc4grF5TZwFoD00Gj8b0xvpmFSeZj36X/bJPa7x3za3j7Cfeetw==", + "workspaces": [ + "packages/preview2-shim" + ], + "dependencies": { "@bytecodealliance/preview2-shim": "^0.16.1", - "mocha": "^10.2.0" + "binaryen": "^116.0.0", + "chalk-template": "^1", + "commander": "^12", + "mkdirp": "^3", + "ora": "^8", + "terser": "^5" + }, + "bin": { + "jco": "src/jco.js" } }, - "node_modules/@bytecodealliance/componentize-js": { - "resolved": "../../../adobe/aio-experiments/ComponentizeJS", - "link": true + "node_modules/@bytecodealliance/preview2-shim": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@bytecodealliance/preview2-shim/-/preview2-shim-0.16.2.tgz", + "integrity": "sha512-36MwesmbLSf3Y5/OHcS85iBaF0N92CQ4gpjtDVKSbrjxmrBKCWlWVfoQ03F/cqDg8k5K7pzVaVBH0XBIbTCfTQ==" + }, + "node_modules/@bytecodealliance/wizer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@bytecodealliance/wizer/-/wizer-3.0.1.tgz", + "integrity": "sha512-f0NBiBHCNBkbFHTPRbA7aKf/t4KyNhi2KvSqw3QzCgi8wFF/uLZ0dhejj93rbiKO/iwWbmU7v9K3SVkW81mcjQ==", + "bin": { + "wizer": "wizer.js" + }, + "engines": { + "node": ">=16" + }, + "optionalDependencies": { + "@bytecodealliance/wizer-darwin-arm64": "3.0.1", + "@bytecodealliance/wizer-darwin-x64": "3.0.1", + "@bytecodealliance/wizer-linux-arm64": "3.0.1", + "@bytecodealliance/wizer-linux-s390x": "3.0.1", + "@bytecodealliance/wizer-linux-x64": "3.0.1", + "@bytecodealliance/wizer-win32-x64": "3.0.1" + } + }, + "node_modules/@bytecodealliance/wizer-darwin-arm64": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@bytecodealliance/wizer-darwin-arm64/-/wizer-darwin-arm64-3.0.1.tgz", + "integrity": "sha512-/8KYSajyhO9koAE3qQhYfC6belZheJw9X3XqW7hrizTpj6n4z4OJFhhqwJmiYFUUsPtC7OxcXMFFPbTuSQPBcw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "bin": { + "wizer-darwin-arm64": "wizer" + } + }, + "node_modules/@bytecodealliance/wizer-darwin-x64": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@bytecodealliance/wizer-darwin-x64/-/wizer-darwin-x64-3.0.1.tgz", + "integrity": "sha512-bMReultN/r+W/BRXV0F+28U5dZwbQT/ZO0k4icZlhUhrv5/wpQJix7Z/ZvBnVQ+/JHb0QDUpFk2/zCtgkRXP6Q==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "bin": { + "wizer-darwin-x64": "wizer" + } + }, + "node_modules/@bytecodealliance/wizer-linux-arm64": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@bytecodealliance/wizer-linux-arm64/-/wizer-linux-arm64-3.0.1.tgz", + "integrity": "sha512-35ZhAeYxWK3bTqqgwysbBWlGlrlMNKNng3ZITQV2PAtafpE7aCeqywl7VAS4lLRG5eTb7wxNgN7zf8d3wiIFTQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "bin": { + "wizer-linux-arm64": "wizer" + } + }, + "node_modules/@bytecodealliance/wizer-linux-s390x": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@bytecodealliance/wizer-linux-s390x/-/wizer-linux-s390x-3.0.1.tgz", + "integrity": "sha512-Smvy9mguEMtX0lupDLTPshXUzAHeOhgscr1bhGNjeCCLD1sd8rIjBvWV19Wtra0BL1zTuU2EPOHjR/4k8WoyDg==", + "cpu": [ + "s390x" + ], + "optional": true, + "os": [ + "linux" + ], + "bin": { + "wizer-linux-s390x": "wizer" + } + }, + "node_modules/@bytecodealliance/wizer-linux-x64": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@bytecodealliance/wizer-linux-x64/-/wizer-linux-x64-3.0.1.tgz", + "integrity": "sha512-uUue78xl7iwndsGgTsagHLTLyLBVHhwzuywiwHt1xw8y0X0O8REKRLBoB7+LdM+pttDPdFtKJgbTFL4UPAA7Yw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "bin": { + "wizer-linux-x64": "wizer" + } + }, + "node_modules/@bytecodealliance/wizer-win32-x64": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@bytecodealliance/wizer-win32-x64/-/wizer-win32-x64-3.0.1.tgz", + "integrity": "sha512-ycd38sx1UTZpHZwh8IfH/4N3n0OQUB8awxkUSLXf9PolEd088YbxoPB3noHy4E+L2oYN7KZMrg9517pX0z2RhQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "bin": { + "wizer-win32-x64": "wizer" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", + "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/acorn": { + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } }, "node_modules/ansi-regex": { "version": "5.0.1", @@ -63,6 +252,70 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/binaryen": { + "version": "116.0.0", + "resolved": "https://registry.npmjs.org/binaryen/-/binaryen-116.0.0.tgz", + "integrity": "sha512-Hp0dXC6Cb/rTwWEoUS2BRghObE7g/S9umKtxuTDt3f61G6fNTE/YVew/ezyy3IdHcLx3f17qfh6LwETgCfvWkQ==", + "bin": { + "wasm-opt": "bin/wasm-opt", + "wasm2js": "bin/wasm2js" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + }, + "node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chalk-template": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/chalk-template/-/chalk-template-1.1.0.tgz", + "integrity": "sha512-T2VJbcDuZQ0Tb2EWwSotMPJjgpy1/tGee1BTpUNsGZ/qgNjV2t7Mvu+d4600U564nbLesN1x2dPL+xii174Ekg==", + "dependencies": { + "chalk": "^5.2.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/chalk/chalk-template?sponsor=1" + } + }, + "node_modules/cli-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", + "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==", + "dependencies": { + "restore-cursor": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-spinners": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", + "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/cliui": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", @@ -110,6 +363,24 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, + "node_modules/commander": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "engines": { + "node": ">=18" + } + }, + "node_modules/emoji-regex": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz", + "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==" + }, + "node_modules/es-module-lexer": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.3.tgz", + "integrity": "sha512-i1gCgmR9dCl6Vil6UKPI/trA69s08g/syhiDK9TG0Nf1RJjjFI+AzoWW7sPufzkgYAn861skuCwJa0pIIHYxvg==" + }, "node_modules/escalade": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", @@ -126,6 +397,17 @@ "node": "6.* || 8.* || >= 10.*" } }, + "node_modules/get-east-asian-width": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.2.0.tgz", + "integrity": "sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -134,11 +416,142 @@ "node": ">=8" } }, + "node_modules/is-interactive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-2.0.0.tgz", + "integrity": "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-unicode-supported": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.0.0.tgz", + "integrity": "sha512-FRdAyx5lusK1iHG0TWpVtk9+1i+GjrzRffhDg4ovQ7mcidMQ6mj+MhKPmvh7Xwyv5gIS06ns49CA7Sqg7lC22Q==", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/itty-router": { "version": "3.0.12", "resolved": "https://registry.npmjs.org/itty-router/-/itty-router-3.0.12.tgz", "integrity": "sha512-s98XTPhle6GGbaFf0kYrOD3Q8gyhnqvOqkwYijC3AmkceNKqWUp13YHg6dWmqmVv4pP7l7c94XI92I0EXVGO0w==" }, + "node_modules/log-symbols": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-6.0.0.tgz", + "integrity": "sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw==", + "dependencies": { + "chalk": "^5.3.0", + "is-unicode-supported": "^1.3.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-symbols/node_modules/is-unicode-supported": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz", + "integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/mkdirp": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", + "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", + "bin": { + "mkdirp": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-8.0.1.tgz", + "integrity": "sha512-ANIvzobt1rls2BDny5fWZ3ZVKyD6nscLvfFRpQgfWsythlcsVUC9kL0zq6j2Z5z9wwp1kd7wpsD/T9qNPVLCaQ==", + "dependencies": { + "chalk": "^5.3.0", + "cli-cursor": "^4.0.0", + "cli-spinners": "^2.9.2", + "is-interactive": "^2.0.0", + "is-unicode-supported": "^2.0.0", + "log-symbols": "^6.0.0", + "stdin-discarder": "^0.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ora/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, "node_modules/prettier": { "version": "3.2.5", "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz", @@ -162,6 +575,95 @@ "node": ">=0.10.0" } }, + "node_modules/restore-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", + "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/stdin-discarder": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/stdin-discarder/-/stdin-discarder-0.2.2.tgz", + "integrity": "sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ==", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.1.0.tgz", + "integrity": "sha512-SEIJCWiX7Kg4c129n48aDRwLbFb2LJmXXFrWBG4NGaRtMQ3myKPKbwrD1BKqQn74oCoNMBVrfDEr5M9YxCsrkw==", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/string-width/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -173,6 +675,28 @@ "node": ">=8" } }, + "node_modules/terser": { + "version": "5.31.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.0.tgz", + "integrity": "sha512-Q1JFAoUKE5IMfI4Z/lkE/E6+SwgzO+x4tq4v1AyBLRj8VSYvRO6A/rQrPg1yud4g0En9EKI1TvFRF2tQFcoUkg==", + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, "node_modules/typescript": { "version": "5.4.5", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", diff --git a/package.json b/package.json index 2890292a..37ffab85 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ "typescript": "^5.4.3" }, "dependencies": { - "@bytecodealliance/componentize-js": "^0.8.3", + "@bytecodealliance/componentize-js": "https://github.com/fermyon/ComponentizeJS#use_fetch_event", "itty-router": "^3.0.12", "yargs": "^17.7.2" } diff --git a/src/inboundHttp.ts b/src/inboundHttp.ts index 84d8c5fe..34f003ab 100644 --- a/src/inboundHttp.ts +++ b/src/inboundHttp.ts @@ -1,121 +1,15 @@ -import { - ResponseOutparam, - Fields, - OutgoingResponse, - OutgoingBody, - // @ts-ignore -} from 'wasi:http/types@0.2.0'; -import { - headers, - IncomingRequest, - OutputStream, - OutgoingResponse as OutgoingResponseType, - OutgoingBody as OutgoingBodyType, -} from './types/wasi-http'; - -const decoder = new TextDecoder(); -const encoder = new TextEncoder(); - -const MAX_BLOCKING_BODY_READ_SIZE = 16 * 1024; -const MAX_BLOCKING_BODY_WRITE_SIZE = 4 * 1024; - -export abstract class HttpHandler { - abstract handleRequest(req: HttpRequest, res: ResponseBuilder): Promise; - - handle = async ( - request: IncomingRequest, - responseOut: OutputStream, - ): Promise => { - let method = request.method(); - - let requestBody = request.consume(); - let requestStream = requestBody.stream(); - let body = new Uint8Array(); - - while (true) { - try { - body = new Uint8Array([ - ...body, - ...requestStream.blockingRead(MAX_BLOCKING_BODY_READ_SIZE), - ]); - } catch (e: any) { - if (e.payload?.tag === 'closed') { - break; - } - throw e; - } - } - - let requestUri = request.pathWithQuery(); - let url = requestUri ? requestUri : '/'; - - let headers = new Headers(); - request - .headers() - .entries() - .forEach(([key, value]) => { - headers.append(key, decoder.decode(value)); - }); - - let req: HttpRequest = { - method: method.tag.toString().toUpperCase(), - uri: url, - headers: headers, - body: body, - text: () => { - return decoder.decode(body); - }, - json: (): any => { - return JSON.parse(decoder.decode(body)); - }, - }; - - let res = new ResponseBuilder(responseOut); - try { - await this.handleRequest(req, res); - } catch (e: any) { - console.log(e.message); - } - }; -} - -export interface WasiHttpRequest { - method: string; - uri: string; - headers: Headers; - body?: Uint8Array; -} - -export interface HttpRequest extends WasiHttpRequest { - text: () => string; - json: () => any; -} - -// FormData and Blob need to be added -export type BodyInit = - | BufferSource - | URLSearchParams - | ReadableStream - | USVString; - -export type USVString = string | ArrayBuffer | ArrayBufferView; +type ResolveFunction = (value: Response | PromiseLike) => void; export class ResponseBuilder { - headers: Headers; - private hasWrittenHeaders: boolean; - private hasSentResponse: boolean; - private responseOut: OutputStream; - private statusCode: number; - private responseBody: OutgoingBodyType | undefined; - private responseStream: OutputStream | undefined; - private response: OutgoingResponseType | undefined; - - constructor(responseOut: OutputStream) { - this.responseOut = responseOut; - this.statusCode = 200; - this.headers = new Headers(); - this.hasWrittenHeaders = false; - this.hasSentResponse = false; + headers: Headers = new Headers(); + statusCode: number = 200; + private hasWrittenHeaders: boolean = false; + private hasSentResponse: boolean = false; + private resolveFunction: ResolveFunction; + private streamController: any; + + constructor(resolve: ResolveFunction) { + this.resolveFunction = resolve; } status(code: number): ResponseBuilder { if (this.hasWrittenHeaders) { @@ -149,7 +43,14 @@ export class ResponseBuilder { if (this.hasSentResponse) { throw new Error('Response has already been sent'); } - this.write(value); + if (!this.hasWrittenHeaders) { + this.resolveFunction( + new Response(value, { headers: this.headers, status: this.statusCode }), + ); + this.hasWrittenHeaders = true; + } else { + this.write(value); + } this.end(); this.hasSentResponse = true; } @@ -158,43 +59,43 @@ export class ResponseBuilder { throw new Error('Response has already been sent'); } if (!this.hasWrittenHeaders) { - let headers = new Fields() as headers; - this.headers.forEach((value, key) => { - headers.append(key, encoder.encode(value)); + let temp; + let readableStream = new ReadableStream({ + start(controller) { + controller.enqueue(convertToUint8Array(value)); + let streamController = { + pump: (value: BodyInit) => { + controller.enqueue(convertToUint8Array(value)); + }, + close: () => { + controller.close(); + }, + }; + temp = streamController; + }, }); - this.response = new OutgoingResponse(headers) as OutgoingResponseType; - this.responseBody = this.response.body(); - this.responseStream = this.responseBody.write(); - this.response.setStatusCode(this.statusCode); - ResponseOutparam.set(this.responseOut, { tag: 'ok', val: this.response }); + this.streamController = temp; + this.resolveFunction( + new Response(readableStream, { + headers: this.headers, + status: this.statusCode, + }), + ); this.hasWrittenHeaders = true; + return; } - writeBytesToOutputStream(value, this.responseStream!); + this.streamController.pump(convertToUint8Array(value)); } end() { if (this.hasSentResponse) { throw new Error('Response has already been sent'); } - // The OutgoingBody here is untyped because I have not figured out how to do that in typescript yet. - this.responseStream?.[Symbol.dispose](); - OutgoingBody.finish(this.responseBody!, { tag: 'none' }); + // close stream + this.streamController.close(); this.hasSentResponse = true; } } -function writeBytesToOutputStream( - body: BodyInit, - responseStream: OutputStream, -) { - let bytes = convertToUint8Array(body); - let offset = 0; - while (offset < bytes.length) { - const count = Math.min(bytes.length - offset, MAX_BLOCKING_BODY_WRITE_SIZE); - responseStream.blockingWriteAndFlush(bytes.slice(offset, offset + count)); - offset += count; - } -} - function convertToUint8Array(body: BodyInit): Uint8Array { if (body instanceof ArrayBuffer) { return new Uint8Array(body); diff --git a/src/index.ts b/src/index.ts index ff58884c..2d5d5e3d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,4 @@ -import { ResponseBuilder, HttpHandler, HttpRequest } from './inboundHttp'; +import { ResponseBuilder } from './inboundHttp'; import { RedisHandler } from './inboundRedis'; import * as Llm from './llm'; import * as Variables from './variables'; @@ -11,7 +11,6 @@ import * as Mqtt from './mqtt'; import { Router } from './router'; export { - HttpHandler, Router, Llm, Variables, @@ -23,5 +22,4 @@ export { Mqtt, RedisHandler, ResponseBuilder, - HttpRequest, }; diff --git a/src/router.ts b/src/router.ts index 4731eacf..b0951bbb 100644 --- a/src/router.ts +++ b/src/router.ts @@ -1,5 +1,5 @@ import { Router as _router } from 'itty-router'; -import { HttpRequest, ResponseBuilder } from './inboundHttp'; +import { ResponseBuilder } from './inboundHttp'; declare type GenericTraps = { [key: string]: any; @@ -27,12 +27,7 @@ interface RouteHandler { } interface SpinRouteHandler { - ( - metadata: IRequest, - req: HttpRequest, - res: ResponseBuilder, - ...args: any - ): any; + (metadata: IRequest, req: Request, res: ResponseBuilder, ...args: any): any; } declare type RouteEntry = [string, RegExp, RouteHandler[]]; @@ -61,7 +56,7 @@ interface routerType { get(path: string, ...handlers: SpinRouteHandler[]): RouterType; handle(request: RequestLike, ...extras: any): Promise; handleRequest( - request: HttpRequest, + request: Request, response: ResponseBuilder, ...extras: any ): Promise; @@ -93,7 +88,7 @@ function Router(): routerType { return _spinRouter.handle(request, ...extra); }, handleRequest: function ( - request: HttpRequest, + request: Request, response: ResponseBuilder, ...a: any ): Promise { @@ -134,7 +129,7 @@ function wrapRouteHandler(handlers: SpinRouteHandler[]): RouteHandler[] { for (let handler of handlers) { let fn = async ( metadata: IRequest, - req: HttpRequest, + req: Request, res: ResponseBuilder, ...args: any ) => { diff --git a/templates/http-ts/content/package.json b/templates/http-ts/content/package.json index 484a4302..ad5834a0 100644 --- a/templates/http-ts/content/package.json +++ b/templates/http-ts/content/package.json @@ -15,11 +15,9 @@ "ts-loader": "^9.4.1", "typescript": "^4.8.4", "webpack": "^5.74.0", - "webpack-cli": "^4.10.0", - "@bytecodealliance/componentize-js": "^0.8.3", - "yargs": "^17.7.2" + "webpack-cli": "^4.10.0" }, "dependencies": { - "@fermyon/spin-sdk": "^2.0.0-alpha.1" + "@fermyon/spin-sdk": "https://github.com/fermyon/spin-js-sdk#update_to_fetch_event" } } \ No newline at end of file diff --git a/templates/http-ts/content/src/index.ts b/templates/http-ts/content/src/index.ts index 9bb73012..c560a3cb 100644 --- a/templates/http-ts/content/src/index.ts +++ b/templates/http-ts/content/src/index.ts @@ -1,6 +1,6 @@ -import { HttpRequest, ResponseBuilder } from "@fermyon/spin-sdk"; +import { ResponseBuilder } from "@fermyon/spin-sdk"; -export async function handler(req: HttpRequest, res: ResponseBuilder) { - console.log("Request: ", req.uri); - res.send("Hello, Universe!"); -} +export async function handler(req: Request, res: ResponseBuilder) { + console.log(req) + res.send("hello universe") +} \ No newline at end of file diff --git a/templates/http-ts/content/src/spin.ts b/templates/http-ts/content/src/spin.ts index 609ed478..c97c3e50 100644 --- a/templates/http-ts/content/src/spin.ts +++ b/templates/http-ts/content/src/spin.ts @@ -1,10 +1,28 @@ -import { HttpHandler, HttpRequest, ResponseBuilder } from "@fermyon/spin-sdk"; +import { ResponseBuilder } from "@fermyon/spin-sdk"; import { handler } from "."; -class App extends HttpHandler { - handleRequest(req: HttpRequest, res: ResponseBuilder): Promise { - return handler(req, res) - } +//@ts-ignore +addEventListener('fetch', (event: FetchEvent) => { + handleEvent(event) +}); + +async function handleEvent(event: FetchEvent) { + + let resolve: any, reject: any; + let responsePromise = new Promise(async (res, rej) => { + resolve = res; + reject = rej; + }); + //@ts-ignore + event.respondWith(responsePromise); + + let res = new ResponseBuilder(resolve) + + await handler(event.request, res) } -export const incomingHandler = new App() +// Keep wizer happy during pre-init. Should go away +// oncehttps://github.com/bytecodealliance/ComponentizeJS/issues/114 is resolved +export const incomingHandler = { + handle() { } +} \ No newline at end of file diff --git a/templates/http-ts/content/tsconfig.json b/templates/http-ts/content/tsconfig.json index 8d86d98b..851fe99f 100644 --- a/templates/http-ts/content/tsconfig.json +++ b/templates/http-ts/content/tsconfig.json @@ -7,7 +7,8 @@ "jsx": "react", "skipLibCheck": true, "lib": [ - "ES2015" + "ES2015", + "WebWorker" ], "allowJs": true, "strict": true, diff --git a/tsconfig.json b/tsconfig.json index e11bf930..29b2abdc 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -18,6 +18,7 @@ }, "exclude": [ "templates/**/*", + "plugins/**/*", "lib/**/*", "bin/**/*", "test/**/*" From bc626f7dfc4f9ab2518c39c85663f30cfee34d14 Mon Sep 17 00:00:00 2001 From: karthik2804 Date: Tue, 4 Jun 2024 11:11:32 +0200 Subject: [PATCH 2/7] temporarily point at PR branch Signed-off-by: karthik2804 --- templates/http-ts/content/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/http-ts/content/package.json b/templates/http-ts/content/package.json index ad5834a0..8b5e20d0 100644 --- a/templates/http-ts/content/package.json +++ b/templates/http-ts/content/package.json @@ -18,6 +18,6 @@ "webpack-cli": "^4.10.0" }, "dependencies": { - "@fermyon/spin-sdk": "https://github.com/fermyon/spin-js-sdk#update_to_fetch_event" + "@fermyon/spin-sdk": "https://github.com/karthik2804/spin-js-sdk#update_to_fetch_event" } } \ No newline at end of file From 6ac9b48abdbc3d9857363c98a0615d73f0fd7277 Mon Sep 17 00:00:00 2001 From: karthik2804 Date: Tue, 4 Jun 2024 20:11:35 +0200 Subject: [PATCH 3/7] allow passing Headers object to res.set Signed-off-by: karthik2804 pull in latest changes Signed-off-by: karthik2804 --- bin/wit/spin.wit | 1 + lib/inboundHttp.d.ts | 2 +- lib/inboundHttp.js | 5 ++ package-lock.json | 131 +++++++++++++++++++++------------------ plugins/webpack/index.js | 2 + src/inboundHttp.ts | 6 +- 6 files changed, 86 insertions(+), 61 deletions(-) diff --git a/bin/wit/spin.wit b/bin/wit/spin.wit index 38431356..1e901776 100644 --- a/bin/wit/spin.wit +++ b/bin/wit/spin.wit @@ -2,6 +2,7 @@ package fermyon:spin@2.0.0; world spin-imports { import wasi:http/outgoing-handler@0.2.0; + include wasi:cli/imports@0.2.0; import llm; import redis; import postgres; diff --git a/lib/inboundHttp.d.ts b/lib/inboundHttp.d.ts index d5e114e6..48877140 100644 --- a/lib/inboundHttp.d.ts +++ b/lib/inboundHttp.d.ts @@ -11,7 +11,7 @@ export declare class ResponseBuilder { getStatus(): number; set(arg1: string | { [key: string]: string; - }, arg2?: string): ResponseBuilder; + } | Headers, arg2?: string): ResponseBuilder; send(value?: BodyInit): void; write(value: BodyInit): void; end(): void; diff --git a/lib/inboundHttp.js b/lib/inboundHttp.js index cef07e79..4bdb2f17 100644 --- a/lib/inboundHttp.js +++ b/lib/inboundHttp.js @@ -23,6 +23,11 @@ export class ResponseBuilder { if (typeof arg1 === 'string' && typeof arg2 === 'string') { this.headers.set(arg1, arg2); } + else if (typeof arg1 === 'object' && arg1 instanceof Headers) { + arg1.forEach((value, key) => { + this.headers.set(key, value); + }); + } else if (typeof arg1 === 'object' && arg2 === undefined) { for (const key in arg1) { this.headers.set(key, arg1[key]); diff --git a/package-lock.json b/package-lock.json index ba2c3ce5..c85e11de 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,7 +23,7 @@ }, "node_modules/@bytecodealliance/componentize-js": { "version": "0.8.3", - "resolved": "git+ssh://git@github.com/fermyon/ComponentizeJS.git#48f77659eedcd8c38200f0368cc61428328aa390", + "resolved": "git+ssh://git@github.com/fermyon/ComponentizeJS.git#afd3fb3096f92fbc0aaa7be065bdf13cf80af421", "workspaces": [ "." ], @@ -231,11 +231,14 @@ } }, "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, "node_modules/ansi-styles": { @@ -329,6 +332,14 @@ "node": ">=12" } }, + "node_modules/cliui/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, "node_modules/cliui/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -347,6 +358,17 @@ "node": ">=8" } }, + "node_modules/cliui/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -527,35 +549,10 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/ora/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/ora/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, "node_modules/prettier": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz", - "integrity": "sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.1.tgz", + "integrity": "sha512-7CAwy5dRsxs8PHXT3twixW9/OEll8MLE0VRPCJyl7CkS6VHGPSlsVaWTiASPTyGyYRyApxlaWTzwUxVNrhcwDg==", "dev": true, "bin": { "prettier": "bin/prettier.cjs" @@ -639,18 +636,7 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/string-width/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/string-width/node_modules/strip-ansi": { + "node_modules/strip-ansi": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", @@ -664,21 +650,10 @@ "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/terser": { - "version": "5.31.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.0.tgz", - "integrity": "sha512-Q1JFAoUKE5IMfI4Z/lkE/E6+SwgzO+x4tq4v1AyBLRj8VSYvRO6A/rQrPg1yud4g0En9EKI1TvFRF2tQFcoUkg==", + "version": "5.31.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.1.tgz", + "integrity": "sha512-37upzU1+viGvuFtBo9NPufCb9dwM0+l9hMxYyWfBA+fbwrPqNJAhbZ6W47bBFnZHKHTUBnMvi87434qq+qnxOg==", "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.8.2", @@ -726,6 +701,14 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, "node_modules/wrap-ansi/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -744,6 +727,17 @@ "node": ">=8" } }, + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", @@ -777,6 +771,14 @@ "node": ">=12" } }, + "node_modules/yargs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, "node_modules/yargs/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -794,6 +796,17 @@ "engines": { "node": ">=8" } + }, + "node_modules/yargs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } } } } diff --git a/plugins/webpack/index.js b/plugins/webpack/index.js index 84b8e802..02cb062b 100644 --- a/plugins/webpack/index.js +++ b/plugins/webpack/index.js @@ -2,6 +2,8 @@ class SpinSdkPlugin { constructor() { this.externals = { "wasi:http/types@0.2.0": "wasi:http/types@0.2.0", + "wasi:cli/environment@0.2.0": "wasi:cli/environment@0.2.0", + "wasi:filesystem/preopens@0.2.0": "wasi:filesystem/preopens@0.2.0", "fermyon:spin/llm@2.0.0": "fermyon:spin/llm@2.0.0", "fermyon:spin/variables@2.0.0": "fermyon:spin/variables@2.0.0", "fermyon:spin/redis@2.0.0": "fermyon:spin/redis@2.0.0", diff --git a/src/inboundHttp.ts b/src/inboundHttp.ts index 34f003ab..96771453 100644 --- a/src/inboundHttp.ts +++ b/src/inboundHttp.ts @@ -22,7 +22,7 @@ export class ResponseBuilder { return this.statusCode; } set( - arg1: string | { [key: string]: string }, + arg1: string | { [key: string]: string } | Headers, arg2?: string, ): ResponseBuilder { if (this.hasWrittenHeaders) { @@ -30,6 +30,10 @@ export class ResponseBuilder { } if (typeof arg1 === 'string' && typeof arg2 === 'string') { this.headers.set(arg1, arg2); + } else if (typeof arg1 === 'object' && arg1 instanceof Headers) { + arg1.forEach((value, key) => { + this.headers.set(key, value); + }); } else if (typeof arg1 === 'object' && arg2 === undefined) { for (const key in arg1) { this.headers.set(key, arg1[key]); From ee18c604f553f8c622b6dc6b7d6fb5b2954565ea Mon Sep 17 00:00:00 2001 From: karthik2804 Date: Thu, 13 Jun 2024 11:59:41 +0200 Subject: [PATCH 4/7] prepare for 2.0.0-aplha.2 release Signed-off-by: karthik2804 --- README.md | 37 +++ lib/inboundHttp.d.ts | 19 -- lib/inboundHttp.js | 115 --------- lib/inboundRedis.d.ts | 3 - lib/inboundRedis.js | 2 - lib/index.d.ts | 12 - lib/index.js | 12 - lib/keyValue.d.ts | 11 - lib/keyValue.js | 42 ---- lib/llm.d.ts | 40 ---- lib/llm.js | 26 -- lib/mqtt.d.ts | 9 - lib/mqtt.js | 11 - lib/mysql.d.ts | 6 - lib/mysql.js | 31 --- lib/postgres.d.ts | 6 - lib/postgres.js | 31 --- lib/rdbmsHelper.d.ts | 2 - lib/rdbmsHelper.js | 39 --- lib/redis.d.ts | 15 -- lib/redis.js | 5 - lib/router.d.ts | 56 ----- lib/router.js | 49 ---- lib/sqlite.d.ts | 32 --- lib/sqlite.js | 77 ------ lib/types/rdbms.d.ts | 108 --------- lib/types/wasi-http.d.ts | 136 ----------- lib/variables.d.ts | 1 - lib/variables.js | 10 - package-lock.json | 318 ++++++++++++++++++++++++- package.json | 2 +- templates/http-ts/content/package.json | 2 +- 32 files changed, 355 insertions(+), 910 deletions(-) delete mode 100644 lib/inboundHttp.d.ts delete mode 100644 lib/inboundHttp.js delete mode 100644 lib/inboundRedis.d.ts delete mode 100644 lib/inboundRedis.js delete mode 100644 lib/index.d.ts delete mode 100644 lib/index.js delete mode 100644 lib/keyValue.d.ts delete mode 100644 lib/keyValue.js delete mode 100644 lib/llm.d.ts delete mode 100644 lib/llm.js delete mode 100644 lib/mqtt.d.ts delete mode 100644 lib/mqtt.js delete mode 100644 lib/mysql.d.ts delete mode 100644 lib/mysql.js delete mode 100644 lib/postgres.d.ts delete mode 100644 lib/postgres.js delete mode 100644 lib/rdbmsHelper.d.ts delete mode 100644 lib/rdbmsHelper.js delete mode 100644 lib/redis.d.ts delete mode 100644 lib/redis.js delete mode 100644 lib/router.d.ts delete mode 100644 lib/router.js delete mode 100644 lib/sqlite.d.ts delete mode 100644 lib/sqlite.js delete mode 100644 lib/types/rdbms.d.ts delete mode 100644 lib/types/wasi-http.d.ts delete mode 100644 lib/variables.d.ts delete mode 100644 lib/variables.js diff --git a/README.md b/README.md index e69de29b..98a49222 100644 --- a/README.md +++ b/README.md @@ -0,0 +1,37 @@ +# Spin JS SDK + +This is an SDK for Javascript and Typescript based on [componentize-js](https://github.com/bytecodealliance/ComponentizeJS). + + +## Installing the templates + +[Spin](https://github.com/fermyon/spin) is a prerequisite. + +The templates can be installed with the following command: + +```bash +spin plugin install --update --git https://github.com/fermyon/spin-js-sdk --branch feat/sdk-v2 +``` + +## Creating and Building a new app= + +```bash +spin new -t http-ts hello-world -a +cd hello-world +npm install +spin buiild +``` + +## Running the app + +```bash +spin up +``` + +## Note: Installing the package + +Currently pre-release versionf are published on NPM and can be installed using the following command: + +```bash +npm install @fermyon/spin-sdk@next +``` \ No newline at end of file diff --git a/lib/inboundHttp.d.ts b/lib/inboundHttp.d.ts deleted file mode 100644 index 48877140..00000000 --- a/lib/inboundHttp.d.ts +++ /dev/null @@ -1,19 +0,0 @@ -type ResolveFunction = (value: Response | PromiseLike) => void; -export declare class ResponseBuilder { - headers: Headers; - statusCode: number; - private hasWrittenHeaders; - private hasSentResponse; - private resolveFunction; - private streamController; - constructor(resolve: ResolveFunction); - status(code: number): ResponseBuilder; - getStatus(): number; - set(arg1: string | { - [key: string]: string; - } | Headers, arg2?: string): ResponseBuilder; - send(value?: BodyInit): void; - write(value: BodyInit): void; - end(): void; -} -export {}; diff --git a/lib/inboundHttp.js b/lib/inboundHttp.js deleted file mode 100644 index 4bdb2f17..00000000 --- a/lib/inboundHttp.js +++ /dev/null @@ -1,115 +0,0 @@ -export class ResponseBuilder { - constructor(resolve) { - this.headers = new Headers(); - this.statusCode = 200; - this.hasWrittenHeaders = false; - this.hasSentResponse = false; - this.resolveFunction = resolve; - } - status(code) { - if (this.hasWrittenHeaders) { - throw new Error('Headers and Status already sent'); - } - this.statusCode = code; - return this; - } - getStatus() { - return this.statusCode; - } - set(arg1, arg2) { - if (this.hasWrittenHeaders) { - throw new Error('Headers already sent'); - } - if (typeof arg1 === 'string' && typeof arg2 === 'string') { - this.headers.set(arg1, arg2); - } - else if (typeof arg1 === 'object' && arg1 instanceof Headers) { - arg1.forEach((value, key) => { - this.headers.set(key, value); - }); - } - else if (typeof arg1 === 'object' && arg2 === undefined) { - for (const key in arg1) { - this.headers.set(key, arg1[key]); - } - } - else { - throw new Error('Invalid arguments'); - } - return this; - } - send(value = new Uint8Array()) { - if (this.hasSentResponse) { - throw new Error('Response has already been sent'); - } - if (!this.hasWrittenHeaders) { - this.resolveFunction(new Response(value, { headers: this.headers, status: this.statusCode })); - this.hasWrittenHeaders = true; - } - else { - this.write(value); - } - this.end(); - this.hasSentResponse = true; - } - write(value) { - if (this.hasSentResponse) { - throw new Error('Response has already been sent'); - } - if (!this.hasWrittenHeaders) { - let temp; - let readableStream = new ReadableStream({ - start(controller) { - controller.enqueue(convertToUint8Array(value)); - let streamController = { - pump: (value) => { - controller.enqueue(convertToUint8Array(value)); - }, - close: () => { - controller.close(); - }, - }; - temp = streamController; - }, - }); - this.streamController = temp; - this.resolveFunction(new Response(readableStream, { - headers: this.headers, - status: this.statusCode, - })); - this.hasWrittenHeaders = true; - return; - } - this.streamController.pump(convertToUint8Array(value)); - } - end() { - if (this.hasSentResponse) { - throw new Error('Response has already been sent'); - } - // close stream - this.streamController.close(); - this.hasSentResponse = true; - } -} -function convertToUint8Array(body) { - if (body instanceof ArrayBuffer) { - return new Uint8Array(body); - } - else if (ArrayBuffer.isView(body)) { - return new Uint8Array(body.buffer, body.byteOffset, body.byteLength); - } - else if (typeof body === 'string') { - const encoder = new TextEncoder(); - const utf8Array = encoder.encode(body); - return utf8Array; - } - else if (body instanceof URLSearchParams) { - const encoder = new TextEncoder(); - const bodyString = body.toString(); - const utf8Array = encoder.encode(bodyString); - return utf8Array; - } - else { - throw new Error('Unsupported body type'); - } -} diff --git a/lib/inboundRedis.d.ts b/lib/inboundRedis.d.ts deleted file mode 100644 index 998a50cf..00000000 --- a/lib/inboundRedis.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -export declare abstract class RedisHandler { - abstract handleMessage(msg: Uint8Array): Promise; -} diff --git a/lib/inboundRedis.js b/lib/inboundRedis.js deleted file mode 100644 index a906b085..00000000 --- a/lib/inboundRedis.js +++ /dev/null @@ -1,2 +0,0 @@ -export class RedisHandler { -} diff --git a/lib/index.d.ts b/lib/index.d.ts deleted file mode 100644 index 2b2b07b6..00000000 --- a/lib/index.d.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { ResponseBuilder } from './inboundHttp'; -import { RedisHandler } from './inboundRedis'; -import * as Llm from './llm'; -import * as Variables from './variables'; -import * as Redis from './redis'; -import * as Kv from './keyValue'; -import * as Sqlite from './sqlite'; -import * as Postgres from './postgres'; -import * as Mysql from './mysql'; -import * as Mqtt from './mqtt'; -import { Router } from './router'; -export { Router, Llm, Variables, Redis, Kv, Sqlite, Postgres, Mysql, Mqtt, RedisHandler, ResponseBuilder, }; diff --git a/lib/index.js b/lib/index.js deleted file mode 100644 index 2b2b07b6..00000000 --- a/lib/index.js +++ /dev/null @@ -1,12 +0,0 @@ -import { ResponseBuilder } from './inboundHttp'; -import { RedisHandler } from './inboundRedis'; -import * as Llm from './llm'; -import * as Variables from './variables'; -import * as Redis from './redis'; -import * as Kv from './keyValue'; -import * as Sqlite from './sqlite'; -import * as Postgres from './postgres'; -import * as Mysql from './mysql'; -import * as Mqtt from './mqtt'; -import { Router } from './router'; -export { Router, Llm, Variables, Redis, Kv, Sqlite, Postgres, Mysql, Mqtt, RedisHandler, ResponseBuilder, }; diff --git a/lib/keyValue.d.ts b/lib/keyValue.d.ts deleted file mode 100644 index 2d78cef8..00000000 --- a/lib/keyValue.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -export interface Store { - get: (key: string) => Uint8Array | null; - set: (key: string, value: Uint8Array | string | object) => void; - delete: (key: string) => void; - exists: (key: string) => boolean; - getKeys: () => string[]; - getJson: (key: string) => any; - setJson: (key: string, value: any) => void; -} -export declare function open(label: string): Store; -export declare function openDefault(): Store; diff --git a/lib/keyValue.js b/lib/keyValue.js deleted file mode 100644 index 26017c03..00000000 --- a/lib/keyValue.js +++ /dev/null @@ -1,42 +0,0 @@ -//@ts-ignore -import * as spinKv from 'fermyon:spin/key-value@2.0.0'; -const encoder = new TextEncoder(); -const decoder = new TextDecoder(); -function createKvStore(store) { - let kv = { - get: (key) => { - return store.get(key); - }, - set: (key, value) => { - if (typeof value === 'string') { - value = encoder.encode(value); - } - else if (typeof value === 'object') { - value = encoder.encode(JSON.stringify(value)); - } - store.set(key, value); - }, - delete: (key) => { - store.delete(key); - }, - exists: (key) => { - return store.exists(key); - }, - getKeys: () => { - return store.getKeys(); - }, - getJson: (key) => { - return JSON.parse(decoder.decode(store.get(key) || new Uint8Array())); - }, - setJson: (key, value) => { - store.set(key, encoder.encode(JSON.stringify(value))); - }, - }; - return kv; -} -export function open(label) { - return createKvStore(spinKv.Store.open(label)); -} -export function openDefault() { - return createKvStore(spinKv.Store.open('default')); -} diff --git a/lib/llm.d.ts b/lib/llm.d.ts deleted file mode 100644 index 4fc01e70..00000000 --- a/lib/llm.d.ts +++ /dev/null @@ -1,40 +0,0 @@ -export declare enum InferencingModels { - Llama2Chat = "llama2-chat", - CodellamaInstruct = "codellama-instruct" -} -export declare enum EmbeddingModels { - AllMiniLmL6V2 = "all-minilm-l6-v2" -} -export interface InferencingOptions { - maxTokens?: number; - repeatPenalty?: number; - repeatPenaltyLastNTokenCount?: number; - temperature?: number; - topK?: number; - topP?: number; -} -export interface InternalInferencingOptions { - maxTokens?: number; - repeatPenalty?: number; - repeatPenaltyLastNTokenCount?: number; - temperature?: number; - topK?: number; - topP?: number; -} -export interface InferenceUsage { - promptTokenCount: number; - generatedTokenCount: number; -} -export interface InferenceResult { - text: string; - usage: InferenceUsage; -} -export interface EmbeddingUsage { - promptTokenCount: number; -} -export interface EmbeddingResult { - embeddings: Array>; - usage: EmbeddingUsage; -} -export declare function infer(model: InferencingModels | string, prompt: string, options?: InferencingOptions): InferenceResult; -export declare const generateEmbeddings: (model: EmbeddingModels | string, text: Array) => EmbeddingResult; diff --git a/lib/llm.js b/lib/llm.js deleted file mode 100644 index 824d28c6..00000000 --- a/lib/llm.js +++ /dev/null @@ -1,26 +0,0 @@ -import { infer as llmInfer, generateEmbeddings as llmGenerateEmbeddings, -//@ts-ignore - } from 'fermyon:spin/llm@2.0.0'; -export var InferencingModels; -(function (InferencingModels) { - InferencingModels["Llama2Chat"] = "llama2-chat"; - InferencingModels["CodellamaInstruct"] = "codellama-instruct"; -})(InferencingModels || (InferencingModels = {})); -export var EmbeddingModels; -(function (EmbeddingModels) { - EmbeddingModels["AllMiniLmL6V2"] = "all-minilm-l6-v2"; -})(EmbeddingModels || (EmbeddingModels = {})); -export function infer(model, prompt, options) { - let inference_options = { - maxTokens: options?.maxTokens || 100, - repeatPenalty: options?.repeatPenalty || 1.1, - repeatPenaltyLastNTokenCount: options?.repeatPenaltyLastNTokenCount || 64, - temperature: options?.temperature || 0.8, - topK: options?.topK || 40, - topP: options?.topP || 0.9, - }; - return llmInfer(model, prompt, inference_options); -} -export const generateEmbeddings = (model, text) => { - return llmGenerateEmbeddings(model, text); -}; diff --git a/lib/mqtt.d.ts b/lib/mqtt.d.ts deleted file mode 100644 index ad6605b2..00000000 --- a/lib/mqtt.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -export declare enum QoS { - AtMostOnce = "at-most-once", - AtLeastOnce = "at-least-once", - ExactlyOnce = "exactly-once" -} -export interface MqttConnection { - publish: (topic: string, payload: Uint8Array, qos: QoS) => void; -} -export declare function open(address: string, username: string, password: string, keepAliveIntervalInSecs: number): MqttConnection; diff --git a/lib/mqtt.js b/lib/mqtt.js deleted file mode 100644 index 19363e11..00000000 --- a/lib/mqtt.js +++ /dev/null @@ -1,11 +0,0 @@ -//@ts-ignore -import * as spinMqtt from 'fermyon:spin/mqtt@2.0.0'; -export var QoS; -(function (QoS) { - QoS["AtMostOnce"] = "at-most-once"; - QoS["AtLeastOnce"] = "at-least-once"; - QoS["ExactlyOnce"] = "exactly-once"; -})(QoS || (QoS = {})); -export function open(address, username, password, keepAliveIntervalInSecs) { - return spinMqtt.Connection.open(address, username, password, keepAliveIntervalInSecs); -} diff --git a/lib/mysql.d.ts b/lib/mysql.d.ts deleted file mode 100644 index 8969a27f..00000000 --- a/lib/mysql.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { RdbmsParameterValue, RdbmsRowSet } from './types/rdbms'; -export interface MysqlConnection { - query: (statement: string, params: RdbmsParameterValue[]) => RdbmsRowSet; - execute: (statement: string, params: RdbmsParameterValue[]) => number; -} -export declare function open(address: string): MysqlConnection; diff --git a/lib/mysql.js b/lib/mysql.js deleted file mode 100644 index cc1dd2f9..00000000 --- a/lib/mysql.js +++ /dev/null @@ -1,31 +0,0 @@ -//@ts-ignore -import * as spinMysql from 'fermyon:spin/mysql@2.0.0'; -import { convertRdbmsToWitTypes } from './rdbmsHelper'; -function createMysqlConnection(connection) { - return { - query: (statement, params) => { - let santizedParams = convertRdbmsToWitTypes(params); - let ret = connection.query(statement, santizedParams); - let results = { - columns: ret.columns, - rows: [], - }; - ret.rows.map((k, rowIndex) => { - results.rows.push({}); - k.map((val, valIndex) => { - results.rows[rowIndex][results.columns[valIndex].name] = - val.tag == 'db-null' || val.tag == 'unsupported' ? null : val.val; - }); - }); - return results; - }, - execute: (statement, params) => { - let santizedParams = convertRdbmsToWitTypes(params); - let ret = connection.execute(statement, santizedParams); - return ret; - }, - }; -} -export function open(address) { - return createMysqlConnection(spinMysql.Connection.open(address)); -} diff --git a/lib/postgres.d.ts b/lib/postgres.d.ts deleted file mode 100644 index 1ab9bee5..00000000 --- a/lib/postgres.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { RdbmsParameterValue, RdbmsRowSet } from './types/rdbms'; -export interface PostgresConnection { - query: (statement: string, params: RdbmsParameterValue[]) => RdbmsRowSet; - execute: (statement: string, params: RdbmsParameterValue[]) => number; -} -export declare function open(address: string): PostgresConnection; diff --git a/lib/postgres.js b/lib/postgres.js deleted file mode 100644 index 71a743fb..00000000 --- a/lib/postgres.js +++ /dev/null @@ -1,31 +0,0 @@ -//@ts-ignore -import * as spinPg from 'fermyon:spin/postgres@2.0.0'; -import { convertRdbmsToWitTypes } from './rdbmsHelper'; -function createPostgresConnection(connection) { - return { - query: (statement, params) => { - let santizedParams = convertRdbmsToWitTypes(params); - let ret = connection.query(statement, santizedParams); - let results = { - columns: ret.columns, - rows: [], - }; - ret.rows.map((k, rowIndex) => { - results.rows.push({}); - k.map((val, valIndex) => { - results.rows[rowIndex][results.columns[valIndex].name] = - val.tag == 'db-null' || val.tag == 'unsupported' ? null : val.val; - }); - }); - return results; - }, - execute: (statement, params) => { - let santizedParams = convertRdbmsToWitTypes(params); - let ret = connection.execute(statement, santizedParams); - return ret; - }, - }; -} -export function open(address) { - return createPostgresConnection(spinPg.Connection.open(address)); -} diff --git a/lib/rdbmsHelper.d.ts b/lib/rdbmsHelper.d.ts deleted file mode 100644 index e4b5c50a..00000000 --- a/lib/rdbmsHelper.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -import { RdbmsParameterValue, SpinRdbmsParameterValue } from './types/rdbms'; -export declare function convertRdbmsToWitTypes(parameters: RdbmsParameterValue[]): SpinRdbmsParameterValue[]; diff --git a/lib/rdbmsHelper.js b/lib/rdbmsHelper.js deleted file mode 100644 index 6a088775..00000000 --- a/lib/rdbmsHelper.js +++ /dev/null @@ -1,39 +0,0 @@ -export function convertRdbmsToWitTypes(parameters) { - let sanitized = []; - for (let k of parameters) { - if (typeof k === 'object') { - sanitized.push(k); - continue; - } - if (typeof k === 'string') { - sanitized.push({ tag: 'str', val: k }); - continue; - } - if (typeof k === null) { - sanitized.push({ tag: 'db-null' }); - continue; - } - if (typeof k === 'boolean') { - sanitized.push({ tag: 'boolean', val: k }); - continue; - } - if (typeof k === 'bigint') { - sanitized.push({ tag: 'int64', val: k }); - continue; - } - if (typeof k === 'number') { - isFloat(k) - ? sanitized.push({ tag: 'floating64', val: k }) - : sanitized.push({ tag: 'int32', val: k }); - continue; - } - if (k instanceof Uint8Array) { - sanitized.push({ tag: 'binary', val: k }); - continue; - } - } - return sanitized; -} -function isFloat(number) { - return number % 1 !== 0; -} diff --git a/lib/redis.d.ts b/lib/redis.d.ts deleted file mode 100644 index 9dc93449..00000000 --- a/lib/redis.d.ts +++ /dev/null @@ -1,15 +0,0 @@ -export type payload = Uint8Array; -export type redisParameter = number | Uint8Array; -export type redisResult = number | Uint8Array | null | string; -export interface RedisConnection { - publish: (channel: string, payload: payload) => void; - get: (key: string) => payload | null; - set: (key: string, value: payload) => void; - incr: (key: string) => number; - del: (key: string) => number; - sadd: (key: string, value: string[]) => number; - smembers: (key: string) => string[]; - srem: (key: string, value: string[]) => number; - execute: (command: string, args: redisParameter[]) => redisResult[]; -} -export declare function open(address: string): RedisConnection; diff --git a/lib/redis.js b/lib/redis.js deleted file mode 100644 index b938482a..00000000 --- a/lib/redis.js +++ /dev/null @@ -1,5 +0,0 @@ -//@ts-ignore -import * as spinRedis from 'fermyon:spin/redis@2.0.0'; -export function open(address) { - return spinRedis.Connection.open(address); -} diff --git a/lib/router.d.ts b/lib/router.d.ts deleted file mode 100644 index 1594e225..00000000 --- a/lib/router.d.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { ResponseBuilder } from './inboundHttp'; -declare type GenericTraps = { - [key: string]: any; -}; -export declare type RequestLike = { - method: string; - url: string; -} & GenericTraps; -declare type IRequest = { - method: string; - url: string; - params: { - [key: string]: string; - }; - query: { - [key: string]: string | string[] | undefined; - }; - proxy?: any; -} & GenericTraps; -interface RouteHandler { - (request: IRequest, ...args: any): any; -} -interface SpinRouteHandler { - (metadata: IRequest, req: Request, res: ResponseBuilder, ...args: any): any; -} -declare type RouteEntry = [string, RegExp, RouteHandler[]]; -declare type Route = (path: string, ...handlers: RouteHandler[]) => T; -declare type RouterHints = { - all: Route; - delete: Route; - get: Route; - options: Route; - patch: Route; - post: Route; - put: Route; -}; -declare type RouterType = { - __proto__: RouterType; - routes: RouteEntry[]; - handle: (request: RequestLike, ...extra: any) => Promise; -} & RouterHints; -interface routerType { - all(path: string, ...handlers: SpinRouteHandler[]): RouterType; - delete(path: string, ...handlers: SpinRouteHandler[]): RouterType; - get(path: string, ...handlers: SpinRouteHandler[]): RouterType; - handle(request: RequestLike, ...extras: any): Promise; - handleRequest(request: Request, response: ResponseBuilder, ...extras: any): Promise; - options(path: string, ...handlers: SpinRouteHandler[]): RouterType; - patch(path: string, ...handlers: SpinRouteHandler[]): RouterType; - post(path: string, ...handlers: SpinRouteHandler[]): RouterType; - put(path: string, ...handlers: SpinRouteHandler[]): RouterType; - routes: RouteEntry[]; -} -/** @internal */ -declare function Router(): routerType; -export { Router, routerType }; diff --git a/lib/router.js b/lib/router.js deleted file mode 100644 index ec0bf197..00000000 --- a/lib/router.js +++ /dev/null @@ -1,49 +0,0 @@ -import { Router as _router } from 'itty-router'; -/** @internal */ -function Router() { - let _spinRouter = _router(); - return { - all: function (path, ...handlers) { - return _spinRouter.all(path, ...wrapRouteHandler(handlers)); - }, - delete: function (path, ...handlers) { - return _spinRouter.delete(path, ...wrapRouteHandler(handlers)); - }, - get: function (path, ...handlers) { - return _spinRouter.get(path, ...wrapRouteHandler(handlers)); - }, - handle: function (request, ...extra) { - return _spinRouter.handle(request, ...extra); - }, - handleRequest: function (request, response, ...a) { - return _spinRouter.handle({ - method: request.method, - url: request.headers.get('spin-full-url') || '', - }, request, response, ...a); - }, - options: function (path, ...handlers) { - return _spinRouter.options(path, ...wrapRouteHandler(handlers)); - }, - patch: function (path, ...handlers) { - return _spinRouter.patch(path, ...wrapRouteHandler(handlers)); - }, - post: function (path, ...handlers) { - return _spinRouter.post(path, ...wrapRouteHandler(handlers)); - }, - put: function (path, ...handlers) { - return _spinRouter.put(path, ...wrapRouteHandler(handlers)); - }, - routes: _spinRouter.routes, - }; -} -function wrapRouteHandler(handlers) { - let h = []; - for (let handler of handlers) { - let fn = async (metadata, req, res, ...args) => { - return handler(metadata, req, res, args); - }; - h.push(fn); - } - return h; -} -export { Router }; diff --git a/lib/sqlite.d.ts b/lib/sqlite.d.ts deleted file mode 100644 index 2ca863f9..00000000 --- a/lib/sqlite.d.ts +++ /dev/null @@ -1,32 +0,0 @@ -export type sqliteValues = ValueInteger | ValueReal | ValueText | ValueBlob | ValueNull; -export type ParameterValue = sqliteValues | number | bigint | null | string | Uint8Array; -export type ValueInteger = { - tag: 'integer'; - val: number | bigint; -}; -export type ValueReal = { - tag: 'real'; - val: number | bigint; -}; -export type ValueText = { - tag: 'text'; - val: string; -}; -export type ValueBlob = { - tag: 'blob'; - val: Uint8Array; -}; -export type ValueNull = { - tag: 'null'; -}; -export interface SqliteResult { - columns: string[]; - rows: { - [key: string]: number | bigint | null | string | Uint8Array; - }[]; -} -export interface SqliteConnection { - execute: (statement: string, parameters: ParameterValue[]) => SqliteResult; -} -export declare function open(label: string): SqliteConnection; -export declare function openDefault(): SqliteConnection; diff --git a/lib/sqlite.js b/lib/sqlite.js deleted file mode 100644 index fe698729..00000000 --- a/lib/sqlite.js +++ /dev/null @@ -1,77 +0,0 @@ -//@ts-ignore -import * as spinSqlite from 'fermyon:spin/sqlite@2.0.0'; -function createSqliteConnection(connection) { - return { - execute: (statement, parameters) => { - let santizedParams = convertToWitTypes(parameters); - let ret = connection.execute(statement, santizedParams); - let results = { - columns: ret.columns, - rows: [], - }; - ret.rows.map((k, rowIndex) => { - results.rows.push({}); - k.values.map((val, valIndex) => { - results.rows[rowIndex][results.columns[valIndex]] = val.val; - }); - }); - return results; - }, - }; -} -export function open(label) { - return createSqliteConnection(spinSqlite.Connection.open(label)); -} -export function openDefault() { - return createSqliteConnection(spinSqlite.Connection.open('default')); -} -const valueInteger = (value) => { - return { tag: 'integer', val: value }; -}; -const valueReal = (value) => { - return { tag: 'real', val: value }; -}; -const valueText = (value) => { - return { tag: 'text', val: value }; -}; -const valueBlob = (value) => { - return { tag: 'blob', val: value }; -}; -const valueNull = () => { - return { tag: 'null' }; -}; -function convertToWitTypes(parameters) { - let sanitized = []; - for (let k of parameters) { - if (typeof k === 'object') { - sanitized.push(k); - continue; - } - if (typeof k === 'number') { - isFloat(k) - ? sanitized.push(valueReal(k)) - : sanitized.push(valueInteger(k)); - continue; - } - if (typeof k === 'bigint') { - sanitized.push(valueInteger(k)); - continue; - } - if (typeof k === 'string') { - sanitized.push(valueText(k)); - continue; - } - if (k === null) { - sanitized.push(valueNull()); - continue; - } - if (k instanceof Uint8Array) { - sanitized.push(valueBlob(k)); - continue; - } - } - return sanitized; -} -function isFloat(number) { - return number % 1 !== 0; -} diff --git a/lib/types/rdbms.d.ts b/lib/types/rdbms.d.ts deleted file mode 100644 index 2f4b5ea5..00000000 --- a/lib/types/rdbms.d.ts +++ /dev/null @@ -1,108 +0,0 @@ -export type RdbmsValueBoolean = { tag: 'boolean'; val: boolean }; -export type RdbmsValueInt8 = { tag: 'int8'; val: number }; -export type RdbmsValueInt16 = { tag: 'int16'; val: number }; -export type RdbmsValueInt32 = { tag: 'int32'; val: number }; -export type RdbmsValueInt64 = { tag: 'int64'; val: bigint }; -export type RdbmsValueUint8 = { tag: 'uint8'; val: number }; -export type RdbmsValueUint16 = { tag: 'uint16'; val: number }; -export type RdbmsValueUint32 = { tag: 'uint32'; val: number }; -export type RdbmsValueUint64 = { tag: 'uint64'; val: bigint }; -export type RdbmsValueFloating32 = { tag: 'floating32'; val: number }; -export type RdbmsValueFloating64 = { tag: 'floating64'; val: number }; -export type RdbmsValueStr = { tag: 'str'; val: string }; -export type RdbmsValueBinary = { tag: 'binary'; val: Uint8Array }; -export type RdbmsValueDbNull = { tag: 'db-null' }; - -export type SpinRdbmsParameterValue = - | RdbmsValueBoolean - | RdbmsValueInt8 - | RdbmsValueInt16 - | RdbmsValueInt32 - | RdbmsValueInt64 - | RdbmsValueUint8 - | RdbmsValueUint16 - | RdbmsValueUint32 - | RdbmsValueUint64 - | RdbmsValueFloating32 - | RdbmsValueFloating64 - | RdbmsValueStr - | RdbmsValueBinary - | RdbmsValueDbNull; - -export type RdbmsParameterValue = - | SpinRdbmsParameterValue - | number - | bigint - | boolean - | null - | Uint8Array - | string; - -export interface RdbmsColumn { - name: string; - dataType: RdbmsDataType[]; -} - -export type RdbmsRow = RdbmsDbValue[]; - -export interface SpinRdbmsRowSet { - columns: RdbmsColumn[]; - rows: RdbmsRow[]; -} - -export interface RdbmsRowSet { - columns: RdbmsColumn[]; - rows: { - [key: string]: number | boolean | bigint | null | string | Uint8Array; - }[]; -} - -export type RdbmsDbBoolean = { tag: 'boolean'; val: boolean }; -export type RdbmsDbInt8 = { tag: 'int8'; val: number }; -export type RdbmsDbInt16 = { tag: 'int16'; val: number }; -export type RdbmsDbInt32 = { tag: 'int32'; val: number }; -export type RdbmsDbInt64 = { tag: 'int64'; val: number }; -export type RdbmsDbUint8 = { tag: 'uint8'; val: number }; -export type RdbmsDbUint16 = { tag: 'uint16'; val: number }; -export type RdbmsDbUint32 = { tag: 'uint32'; val: number }; -export type RdbmsDbUint64 = { tag: 'uint64'; val: number }; -export type RdbmsDbFloating32 = { tag: 'floating32'; val: number }; -export type RdbmsDbFloating64 = { tag: 'floating64'; val: number }; -export type RdbmsDbStr = { tag: 'str'; val: string }; -export type RdbmsDbBinary = { tag: 'binary'; val: Uint8Array }; -export type RdbmsDbNull = { tag: 'db-null' }; -export type RdbmsDbUnsupported = { tag: 'unsupported' }; - -export type RdbmsDbValue = - | RdbmsDbBoolean - | RdbmsDbInt8 - | RdbmsDbInt16 - | RdbmsDbInt32 - | RdbmsDbInt64 - | RdbmsDbUint8 - | RdbmsDbUint16 - | RdbmsDbUint32 - | RdbmsDbUint64 - | RdbmsDbFloating32 - | RdbmsDbFloating64 - | RdbmsDbStr - | RdbmsDbBinary - | RdbmsDbNull - | RdbmsDbUnsupported; - -export enum RdbmsDataType { - RdbmsBoolean = 'boolean', - RdbmsInt8 = 'int8', - RdbmsInt16 = 'int16', - RdbmsInt32 = 'int32', - RdbmsInt64 = 'int64', - RdbmsUint8 = 'uint8', - RdbmsUint16 = 'uint16', - RdbmsUint32 = 'uint32', - RdbmsUint64 = 'uint64', - RdbmsFloating32 = 'floating32', - RdbmsFloating64 = 'floating64', - RdbmsStr = 'str', - RdbmsBinary = 'binary', - RdbmsOther = 'other', -} diff --git a/lib/types/wasi-http.d.ts b/lib/types/wasi-http.d.ts deleted file mode 100644 index be4852cb..00000000 --- a/lib/types/wasi-http.d.ts +++ /dev/null @@ -1,136 +0,0 @@ -export interface method { - tag: - | 'get' - | 'head' - | 'post' - | 'put' - | 'delete' - | 'connect' - | 'options' - | 'trace' - | 'patch' - | { kind: 'other'; value: string }; -} - -export interface schema { - tag: 'HTTP' | 'HTTPS' | { kind: 'other'; value: string }; -} - -export type FieldValue = Uint8Array; -export type FieldKey = string; - -export declare class headers { - constructor(); - static fromList: (entries: [FieldKey, FieldValue][]) => headers; - get: (name: FieldKey) => FieldValue[]; - has: (name: FieldKey) => boolean; - set: (name: FieldKey, value: FieldValue) => void; - delete: (name: FieldKey) => void; - append: (name: FieldKey, value: FieldValue) => void; - entries: () => [FieldKey, FieldValue][]; - clone: () => headers; -} -export type trailers = headers | { tag: 'none' }; - -export interface Pollable { - read: () => boolean; - block: () => void; -} - -export interface InputStream { - read: (len: number) => Uint8Array; - blockingRead: (len: number) => Uint8Array; - skip: (len: number) => Uint8Array; - blockingSkip: (len: number) => Uint8Array; - subscribe: () => Pollable; -} - -export interface FutureTrailers { - subscribe: () => Pollable; - get: () => trailers | null; -} - -export declare class IncomingBody { - stream: () => InputStream; - static finish: (incomingBody: IncomingBody) => FutureTrailers; -} - -export interface OutputStream { - checkWrite: () => bigint; - write: (content: Uint8Array) => void; - blockingWriteAndFlush: (content: Uint8Array) => void; - flush: () => void; - blockingFlush: () => void; - subscribe: () => Pollable; - writeZeros: (len: number) => void; - blockingWriteZerosAndFlush: (len: number) => void; - splice: (src: InputStream, len: number) => number; - blockingSplice: (src: InputStream, len: number) => number; - [Symbol.dispose](): void; -} - -export declare class OutgoingBody { - write: () => OutputStream; - static finish: ( - outgoingBody: OutgoingBody, - trailers: trailers | null, - ) => void; -} - -export interface IncomingRequest { - method: () => method; - - /// Returns the path with query parameters from the request, as a string. - pathWithQuery: () => string | null; - - /// Returns the protocol scheme from the request. - scheme: () => scheme; - - /// Returns the authority from the request, if it was present. - authority: () => string; - - /// Get the `headers` associated with the request. - /// - /// The returned `headers` resource is immutable: `set`, `append`, and - /// `delete` operations will fail with `header-error.immutable`. - /// - /// The `headers` returned are a child resource: it must be dropped before - /// the parent `incoming-request` is dropped. Dropping this - /// `incoming-request` before all children are dropped will trap. - headers: () => headers; - - /// Gives the `incoming-body` associated with this request. Will only - /// return success at most once, and subsequent calls will return error. - consume: () => IncomingBody; -} - -export declare class OutgoingResponse { - constructor(headers: headers); - /// Get the HTTP Status Code for the Response. - statusCode: () => number; - - /// Set the HTTP Status Code for the Response. Fails if the status-code - /// given is not a valid http status code. - setStatusCode: (statusCode: number) => void; - - /// Get the headers associated with the Request. - /// - /// The returned `headers` resource is immutable: `set`, `append`, and - /// `delete` operations will fail with `header-error.immutable`. - /// - /// This headers resource is a child: it must be dropped before the parent - /// `outgoing-request` is dropped, or its ownership is transfered to - /// another component by e.g. `outgoing-handler.handle`. - headers: () => headers; - - /// Returns the resource corresponding to the outgoing Body for this Response. - /// - /// Returns success on the first call: the `outgoing-body` resource for - /// this `outgoing-response` can be retrieved at most once. Subsequent - /// calls will return error. - body: () => OutgoingBody; -} - -export declare class ResponseOutparam { - static set: (param: ResponseOutparam, response: OutgoingResponse) => void; -} diff --git a/lib/variables.d.ts b/lib/variables.d.ts deleted file mode 100644 index cb1928a1..00000000 --- a/lib/variables.d.ts +++ /dev/null @@ -1 +0,0 @@ -export declare function get(key: string): string | null; diff --git a/lib/variables.js b/lib/variables.js deleted file mode 100644 index 35699e1d..00000000 --- a/lib/variables.js +++ /dev/null @@ -1,10 +0,0 @@ -//@ts-ignore -import { get as spinGet } from 'fermyon:spin/variables@2.0.0'; -export function get(key) { - try { - return spinGet(key); - } - catch (e) { - return null; - } -} diff --git a/package-lock.json b/package-lock.json index c85e11de..7dfb9069 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,15 +1,16 @@ { "name": "@fermyon/spin-sdk", - "version": "2.0.0-alpha.1", + "version": "2.0.0-alpha.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@fermyon/spin-sdk", - "version": "2.0.0-alpha.1", + "version": "2.0.0-alpha.2", "license": "Apache-2.0", "dependencies": { "@bytecodealliance/componentize-js": "https://github.com/fermyon/ComponentizeJS#use_fetch_event", + "d3": "^6.0.0-rc.4", "itty-router": "^3.0.12", "yargs": "^17.7.2" }, @@ -393,6 +394,293 @@ "node": ">=18" } }, + "node_modules/d3": { + "version": "6.0.0-rc.4", + "resolved": "https://registry.npmjs.org/d3/-/d3-6.0.0-rc.4.tgz", + "integrity": "sha512-Wpu0Ibnx2O316I+eoeZtYoAITKALlQhrXsZdxH2TWDkPGkEHqwpwjwsIFtLEkTlKkBzPhMkvVYPROuB2HPpB7w==", + "dependencies": { + "d3-array": "^2.5", + "d3-axis": "2", + "d3-brush": "2", + "d3-chord": "2", + "d3-color": "2", + "d3-contour": "2", + "d3-delaunay": "5", + "d3-dispatch": "2", + "d3-drag": "2", + "d3-dsv": "2", + "d3-ease": "2", + "d3-fetch": "2", + "d3-force": "2", + "d3-format": "2", + "d3-geo": "2", + "d3-hierarchy": "2", + "d3-interpolate": "2", + "d3-path": "2", + "d3-polygon": "2", + "d3-quadtree": "2", + "d3-random": "2", + "d3-scale": "3", + "d3-scale-chromatic": "2", + "d3-selection": "2", + "d3-shape": "2", + "d3-time": "2", + "d3-time-format": "3", + "d3-timer": "2", + "d3-transition": "2", + "d3-zoom": "2" + } + }, + "node_modules/d3-array": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz", + "integrity": "sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==", + "dependencies": { + "internmap": "^1.0.0" + } + }, + "node_modules/d3-axis": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-2.1.0.tgz", + "integrity": "sha512-z/G2TQMyuf0X3qP+Mh+2PimoJD41VOCjViJzT0BHeL/+JQAofkiWZbWxlwFGb1N8EN+Cl/CW+MUKbVzr1689Cw==" + }, + "node_modules/d3-brush": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-2.1.0.tgz", + "integrity": "sha512-cHLLAFatBATyIKqZOkk/mDHUbzne2B3ZwxkzMHvFTCZCmLaXDpZRihQSn8UNXTkGD/3lb/W2sQz0etAftmHMJQ==", + "dependencies": { + "d3-dispatch": "1 - 2", + "d3-drag": "2", + "d3-interpolate": "1 - 2", + "d3-selection": "2", + "d3-transition": "2" + } + }, + "node_modules/d3-chord": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-2.0.0.tgz", + "integrity": "sha512-D5PZb7EDsRNdGU4SsjQyKhja8Zgu+SHZfUSO5Ls8Wsn+jsAKUUGkcshLxMg9HDFxG3KqavGWaWkJ8EpU8ojuig==", + "dependencies": { + "d3-path": "1 - 2" + } + }, + "node_modules/d3-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-2.0.0.tgz", + "integrity": "sha512-SPXi0TSKPD4g9tw0NMZFnR95XVgUZiBH+uUTqQuDu1OsE2zomHU7ho0FISciaPvosimixwHFl3WHLGabv6dDgQ==" + }, + "node_modules/d3-contour": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-contour/-/d3-contour-2.0.0.tgz", + "integrity": "sha512-9unAtvIaNk06UwqBmvsdHX7CZ+NPDZnn8TtNH1myW93pWJkhsV25JcgnYAu0Ck5Veb1DHiCv++Ic5uvJ+h50JA==", + "dependencies": { + "d3-array": "2" + } + }, + "node_modules/d3-delaunay": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-5.3.0.tgz", + "integrity": "sha512-amALSrOllWVLaHTnDLHwMIiz0d1bBu9gZXd1FiLfXf8sHcX9jrcj81TVZOqD4UX7MgBZZ07c8GxzEgBpJqc74w==", + "dependencies": { + "delaunator": "4" + } + }, + "node_modules/d3-dispatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-2.0.0.tgz", + "integrity": "sha512-S/m2VsXI7gAti2pBoLClFFTMOO1HTtT0j99AuXLoGFKO6deHDdnv6ZGTxSTTUTgO1zVcv82fCOtDjYK4EECmWA==" + }, + "node_modules/d3-drag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-2.0.0.tgz", + "integrity": "sha512-g9y9WbMnF5uqB9qKqwIIa/921RYWzlUDv9Jl1/yONQwxbOfszAWTCm8u7HOTgJgRDXiRZN56cHT9pd24dmXs8w==", + "dependencies": { + "d3-dispatch": "1 - 2", + "d3-selection": "2" + } + }, + "node_modules/d3-dsv": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-2.0.0.tgz", + "integrity": "sha512-E+Pn8UJYx9mViuIUkoc93gJGGYut6mSDKy2+XaPwccwkRGlR+LO97L2VCCRjQivTwLHkSnAJG7yo00BWY6QM+w==", + "dependencies": { + "commander": "2", + "iconv-lite": "0.4", + "rw": "1" + }, + "bin": { + "csv2json": "bin/dsv2json", + "csv2tsv": "bin/dsv2dsv", + "dsv2dsv": "bin/dsv2dsv", + "dsv2json": "bin/dsv2json", + "json2csv": "bin/json2dsv", + "json2dsv": "bin/json2dsv", + "json2tsv": "bin/json2dsv", + "tsv2csv": "bin/dsv2dsv", + "tsv2json": "bin/dsv2json" + } + }, + "node_modules/d3-dsv/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "node_modules/d3-ease": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-2.0.0.tgz", + "integrity": "sha512-68/n9JWarxXkOWMshcT5IcjbB+agblQUaIsbnXmrzejn2O82n3p2A9R2zEB9HIEFWKFwPAEDDN8gR0VdSAyyAQ==" + }, + "node_modules/d3-fetch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-fetch/-/d3-fetch-2.0.0.tgz", + "integrity": "sha512-TkYv/hjXgCryBeNKiclrwqZH7Nb+GaOwo3Neg24ZVWA3MKB+Rd+BY84Nh6tmNEMcjUik1CSUWjXYndmeO6F7sw==", + "dependencies": { + "d3-dsv": "1 - 2" + } + }, + "node_modules/d3-force": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-2.1.1.tgz", + "integrity": "sha512-nAuHEzBqMvpFVMf9OX75d00OxvOXdxY+xECIXjW6Gv8BRrXu6gAWbv/9XKrvfJ5i5DCokDW7RYE50LRoK092ew==", + "dependencies": { + "d3-dispatch": "1 - 2", + "d3-quadtree": "1 - 2", + "d3-timer": "1 - 2" + } + }, + "node_modules/d3-format": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-2.0.0.tgz", + "integrity": "sha512-Ab3S6XuE/Q+flY96HXT0jOXcM4EAClYFnRGY5zsjRGNy6qCYrQsMffs7cV5Q9xejb35zxW5hf/guKw34kvIKsA==" + }, + "node_modules/d3-geo": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-2.0.2.tgz", + "integrity": "sha512-8pM1WGMLGFuhq9S+FpPURxic+gKzjluCD/CHTuUF3mXMeiCo0i6R0tO1s4+GArRFde96SLcW/kOFRjoAosPsFA==", + "dependencies": { + "d3-array": "^2.5.0" + } + }, + "node_modules/d3-hierarchy": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-2.0.0.tgz", + "integrity": "sha512-SwIdqM3HxQX2214EG9GTjgmCc/mbSx4mQBn+DuEETubhOw6/U3fmnji4uCVrmzOydMHSO1nZle5gh6HB/wdOzw==" + }, + "node_modules/d3-interpolate": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-2.0.1.tgz", + "integrity": "sha512-c5UhwwTs/yybcmTpAVqwSFl6vrQ8JZJoT5F7xNFK9pymv5C0Ymcc9/LIJHtYIggg/yS9YHw8i8O8tgb9pupjeQ==", + "dependencies": { + "d3-color": "1 - 2" + } + }, + "node_modules/d3-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-2.0.0.tgz", + "integrity": "sha512-ZwZQxKhBnv9yHaiWd6ZU4x5BtCQ7pXszEV9CU6kRgwIQVQGLMv1oiL4M+MK/n79sYzsj+gcgpPQSctJUsLN7fA==" + }, + "node_modules/d3-polygon": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-2.0.0.tgz", + "integrity": "sha512-MsexrCK38cTGermELs0cO1d79DcTsQRN7IWMJKczD/2kBjzNXxLUWP33qRF6VDpiLV/4EI4r6Gs0DAWQkE8pSQ==" + }, + "node_modules/d3-quadtree": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-2.0.0.tgz", + "integrity": "sha512-b0Ed2t1UUalJpc3qXzKi+cPGxeXRr4KU9YSlocN74aTzp6R/Ud43t79yLLqxHRWZfsvWXmbDWPpoENK1K539xw==" + }, + "node_modules/d3-random": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/d3-random/-/d3-random-2.2.2.tgz", + "integrity": "sha512-0D9P8TRj6qDAtHhRQn6EfdOtHMfsUWanl3yb/84C4DqpZ+VsgfI5iTVRNRbELCfNvRfpMr8OrqqUTQ6ANGCijw==" + }, + "node_modules/d3-scale": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-3.3.0.tgz", + "integrity": "sha512-1JGp44NQCt5d1g+Yy+GeOnZP7xHo0ii8zsQp6PGzd+C1/dl0KGsp9A7Mxwp+1D1o4unbTTxVdU/ZOIEBoeZPbQ==", + "dependencies": { + "d3-array": "^2.3.0", + "d3-format": "1 - 2", + "d3-interpolate": "1.2.0 - 2", + "d3-time": "^2.1.1", + "d3-time-format": "2 - 3" + } + }, + "node_modules/d3-scale-chromatic": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-2.0.0.tgz", + "integrity": "sha512-LLqy7dJSL8yDy7NRmf6xSlsFZ6zYvJ4BcWFE4zBrOPnQERv9zj24ohnXKRbyi9YHnYV+HN1oEO3iFK971/gkzA==", + "dependencies": { + "d3-color": "1 - 2", + "d3-interpolate": "1 - 2" + } + }, + "node_modules/d3-selection": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-2.0.0.tgz", + "integrity": "sha512-XoGGqhLUN/W14NmaqcO/bb1nqjDAw5WtSYb2X8wiuQWvSZUsUVYsOSkOybUrNvcBjaywBdYPy03eXHMXjk9nZA==" + }, + "node_modules/d3-shape": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-2.1.0.tgz", + "integrity": "sha512-PnjUqfM2PpskbSLTJvAzp2Wv4CZsnAgTfcVRTwW03QR3MkXF8Uo7B1y/lWkAsmbKwuecto++4NlsYcvYpXpTHA==", + "dependencies": { + "d3-path": "1 - 2" + } + }, + "node_modules/d3-time": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-2.1.1.tgz", + "integrity": "sha512-/eIQe/eR4kCQwq7yxi7z4c6qEXf2IYGcjoWB5OOQy4Tq9Uv39/947qlDcN2TLkiTzQWzvnsuYPB9TrWaNfipKQ==", + "dependencies": { + "d3-array": "2" + } + }, + "node_modules/d3-time-format": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-3.0.0.tgz", + "integrity": "sha512-UXJh6EKsHBTjopVqZBhFysQcoXSv/5yLONZvkQ5Kk3qbwiUYkdX17Xa1PT6U1ZWXGGfB1ey5L8dKMlFq2DO0Ag==", + "dependencies": { + "d3-time": "1 - 2" + } + }, + "node_modules/d3-timer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-2.0.0.tgz", + "integrity": "sha512-TO4VLh0/420Y/9dO3+f9abDEFYeCUr2WZRlxJvbp4HPTQcSylXNiL6yZa9FIUvV1yRiFufl1bszTCLDqv9PWNA==" + }, + "node_modules/d3-transition": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-2.0.0.tgz", + "integrity": "sha512-42ltAGgJesfQE3u9LuuBHNbGrI/AJjNL2OAUdclE70UE6Vy239GCBEYD38uBPoLeNsOhFStGpPI0BAOV+HMxog==", + "dependencies": { + "d3-color": "1 - 2", + "d3-dispatch": "1 - 2", + "d3-ease": "1 - 2", + "d3-interpolate": "1 - 2", + "d3-timer": "1 - 2" + }, + "peerDependencies": { + "d3-selection": "2" + } + }, + "node_modules/d3-zoom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-2.0.0.tgz", + "integrity": "sha512-fFg7aoaEm9/jf+qfstak0IYpnesZLiMX6GZvXtUSdv8RH2o4E2qeelgdU09eKS6wGuiGMfcnMI0nTIqWzRHGpw==", + "dependencies": { + "d3-dispatch": "1 - 2", + "d3-drag": "2", + "d3-interpolate": "1 - 2", + "d3-selection": "2", + "d3-transition": "2" + } + }, + "node_modules/delaunator": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-4.0.1.tgz", + "integrity": "sha512-WNPWi1IRKZfCt/qIDMfERkDp93+iZEmOxN2yy4Jg+Xhv8SLk2UTqqbe1sfiipn0and9QrE914/ihdx82Y/Giag==" + }, "node_modules/emoji-regex": { "version": "10.3.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz", @@ -430,6 +718,22 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/internmap": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-1.0.1.tgz", + "integrity": "sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==" + }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -587,6 +891,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/rw": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", + "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, "node_modules/signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", diff --git a/package.json b/package.json index 37ffab85..9208829e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@fermyon/spin-sdk", - "version": "2.0.0-alpha.1", + "version": "2.0.0-alpha.2", "description": "", "main": "lib/index.js", "typings": "lib/index.d.ts", diff --git a/templates/http-ts/content/package.json b/templates/http-ts/content/package.json index 8b5e20d0..fb5f121e 100644 --- a/templates/http-ts/content/package.json +++ b/templates/http-ts/content/package.json @@ -18,6 +18,6 @@ "webpack-cli": "^4.10.0" }, "dependencies": { - "@fermyon/spin-sdk": "https://github.com/karthik2804/spin-js-sdk#update_to_fetch_event" + "@fermyon/spin-sdk": "^2.0.0-alpha.2" } } \ No newline at end of file From 7ab21b6b0308061f509f588d876d38bf28e638e4 Mon Sep 17 00:00:00 2001 From: karthik2804 Date: Mon, 17 Jun 2024 10:10:56 +0200 Subject: [PATCH 5/7] clean up response builder Signed-off-by: karthik2804 --- package-lock.json | 322 +-------------------------------------------- src/inboundHttp.ts | 48 ++++--- 2 files changed, 27 insertions(+), 343 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7dfb9069..197d8527 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,6 @@ "license": "Apache-2.0", "dependencies": { "@bytecodealliance/componentize-js": "https://github.com/fermyon/ComponentizeJS#use_fetch_event", - "d3": "^6.0.0-rc.4", "itty-router": "^3.0.12", "yargs": "^17.7.2" }, @@ -24,7 +23,7 @@ }, "node_modules/@bytecodealliance/componentize-js": { "version": "0.8.3", - "resolved": "git+ssh://git@github.com/fermyon/ComponentizeJS.git#afd3fb3096f92fbc0aaa7be065bdf13cf80af421", + "resolved": "git+ssh://git@github.com/fermyon/ComponentizeJS.git#c3107d1240ca0e1b5b7d3bdad95f0168a1a808ef", "workspaces": [ "." ], @@ -221,9 +220,9 @@ } }, "node_modules/acorn": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", - "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.0.tgz", + "integrity": "sha512-RTvkC4w+KNXrM39/lWCUaG0IbRkWdCv7W/IOW9oU6SawyxulvkQy5HQPVTKxEjczcUvapcrw3cFx/60VN/NRNw==", "bin": { "acorn": "bin/acorn" }, @@ -394,293 +393,6 @@ "node": ">=18" } }, - "node_modules/d3": { - "version": "6.0.0-rc.4", - "resolved": "https://registry.npmjs.org/d3/-/d3-6.0.0-rc.4.tgz", - "integrity": "sha512-Wpu0Ibnx2O316I+eoeZtYoAITKALlQhrXsZdxH2TWDkPGkEHqwpwjwsIFtLEkTlKkBzPhMkvVYPROuB2HPpB7w==", - "dependencies": { - "d3-array": "^2.5", - "d3-axis": "2", - "d3-brush": "2", - "d3-chord": "2", - "d3-color": "2", - "d3-contour": "2", - "d3-delaunay": "5", - "d3-dispatch": "2", - "d3-drag": "2", - "d3-dsv": "2", - "d3-ease": "2", - "d3-fetch": "2", - "d3-force": "2", - "d3-format": "2", - "d3-geo": "2", - "d3-hierarchy": "2", - "d3-interpolate": "2", - "d3-path": "2", - "d3-polygon": "2", - "d3-quadtree": "2", - "d3-random": "2", - "d3-scale": "3", - "d3-scale-chromatic": "2", - "d3-selection": "2", - "d3-shape": "2", - "d3-time": "2", - "d3-time-format": "3", - "d3-timer": "2", - "d3-transition": "2", - "d3-zoom": "2" - } - }, - "node_modules/d3-array": { - "version": "2.12.1", - "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz", - "integrity": "sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==", - "dependencies": { - "internmap": "^1.0.0" - } - }, - "node_modules/d3-axis": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-2.1.0.tgz", - "integrity": "sha512-z/G2TQMyuf0X3qP+Mh+2PimoJD41VOCjViJzT0BHeL/+JQAofkiWZbWxlwFGb1N8EN+Cl/CW+MUKbVzr1689Cw==" - }, - "node_modules/d3-brush": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-2.1.0.tgz", - "integrity": "sha512-cHLLAFatBATyIKqZOkk/mDHUbzne2B3ZwxkzMHvFTCZCmLaXDpZRihQSn8UNXTkGD/3lb/W2sQz0etAftmHMJQ==", - "dependencies": { - "d3-dispatch": "1 - 2", - "d3-drag": "2", - "d3-interpolate": "1 - 2", - "d3-selection": "2", - "d3-transition": "2" - } - }, - "node_modules/d3-chord": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-2.0.0.tgz", - "integrity": "sha512-D5PZb7EDsRNdGU4SsjQyKhja8Zgu+SHZfUSO5Ls8Wsn+jsAKUUGkcshLxMg9HDFxG3KqavGWaWkJ8EpU8ojuig==", - "dependencies": { - "d3-path": "1 - 2" - } - }, - "node_modules/d3-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-2.0.0.tgz", - "integrity": "sha512-SPXi0TSKPD4g9tw0NMZFnR95XVgUZiBH+uUTqQuDu1OsE2zomHU7ho0FISciaPvosimixwHFl3WHLGabv6dDgQ==" - }, - "node_modules/d3-contour": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/d3-contour/-/d3-contour-2.0.0.tgz", - "integrity": "sha512-9unAtvIaNk06UwqBmvsdHX7CZ+NPDZnn8TtNH1myW93pWJkhsV25JcgnYAu0Ck5Veb1DHiCv++Ic5uvJ+h50JA==", - "dependencies": { - "d3-array": "2" - } - }, - "node_modules/d3-delaunay": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-5.3.0.tgz", - "integrity": "sha512-amALSrOllWVLaHTnDLHwMIiz0d1bBu9gZXd1FiLfXf8sHcX9jrcj81TVZOqD4UX7MgBZZ07c8GxzEgBpJqc74w==", - "dependencies": { - "delaunator": "4" - } - }, - "node_modules/d3-dispatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-2.0.0.tgz", - "integrity": "sha512-S/m2VsXI7gAti2pBoLClFFTMOO1HTtT0j99AuXLoGFKO6deHDdnv6ZGTxSTTUTgO1zVcv82fCOtDjYK4EECmWA==" - }, - "node_modules/d3-drag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-2.0.0.tgz", - "integrity": "sha512-g9y9WbMnF5uqB9qKqwIIa/921RYWzlUDv9Jl1/yONQwxbOfszAWTCm8u7HOTgJgRDXiRZN56cHT9pd24dmXs8w==", - "dependencies": { - "d3-dispatch": "1 - 2", - "d3-selection": "2" - } - }, - "node_modules/d3-dsv": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-2.0.0.tgz", - "integrity": "sha512-E+Pn8UJYx9mViuIUkoc93gJGGYut6mSDKy2+XaPwccwkRGlR+LO97L2VCCRjQivTwLHkSnAJG7yo00BWY6QM+w==", - "dependencies": { - "commander": "2", - "iconv-lite": "0.4", - "rw": "1" - }, - "bin": { - "csv2json": "bin/dsv2json", - "csv2tsv": "bin/dsv2dsv", - "dsv2dsv": "bin/dsv2dsv", - "dsv2json": "bin/dsv2json", - "json2csv": "bin/json2dsv", - "json2dsv": "bin/json2dsv", - "json2tsv": "bin/json2dsv", - "tsv2csv": "bin/dsv2dsv", - "tsv2json": "bin/dsv2json" - } - }, - "node_modules/d3-dsv/node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" - }, - "node_modules/d3-ease": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-2.0.0.tgz", - "integrity": "sha512-68/n9JWarxXkOWMshcT5IcjbB+agblQUaIsbnXmrzejn2O82n3p2A9R2zEB9HIEFWKFwPAEDDN8gR0VdSAyyAQ==" - }, - "node_modules/d3-fetch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/d3-fetch/-/d3-fetch-2.0.0.tgz", - "integrity": "sha512-TkYv/hjXgCryBeNKiclrwqZH7Nb+GaOwo3Neg24ZVWA3MKB+Rd+BY84Nh6tmNEMcjUik1CSUWjXYndmeO6F7sw==", - "dependencies": { - "d3-dsv": "1 - 2" - } - }, - "node_modules/d3-force": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-2.1.1.tgz", - "integrity": "sha512-nAuHEzBqMvpFVMf9OX75d00OxvOXdxY+xECIXjW6Gv8BRrXu6gAWbv/9XKrvfJ5i5DCokDW7RYE50LRoK092ew==", - "dependencies": { - "d3-dispatch": "1 - 2", - "d3-quadtree": "1 - 2", - "d3-timer": "1 - 2" - } - }, - "node_modules/d3-format": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-2.0.0.tgz", - "integrity": "sha512-Ab3S6XuE/Q+flY96HXT0jOXcM4EAClYFnRGY5zsjRGNy6qCYrQsMffs7cV5Q9xejb35zxW5hf/guKw34kvIKsA==" - }, - "node_modules/d3-geo": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-2.0.2.tgz", - "integrity": "sha512-8pM1WGMLGFuhq9S+FpPURxic+gKzjluCD/CHTuUF3mXMeiCo0i6R0tO1s4+GArRFde96SLcW/kOFRjoAosPsFA==", - "dependencies": { - "d3-array": "^2.5.0" - } - }, - "node_modules/d3-hierarchy": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-2.0.0.tgz", - "integrity": "sha512-SwIdqM3HxQX2214EG9GTjgmCc/mbSx4mQBn+DuEETubhOw6/U3fmnji4uCVrmzOydMHSO1nZle5gh6HB/wdOzw==" - }, - "node_modules/d3-interpolate": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-2.0.1.tgz", - "integrity": "sha512-c5UhwwTs/yybcmTpAVqwSFl6vrQ8JZJoT5F7xNFK9pymv5C0Ymcc9/LIJHtYIggg/yS9YHw8i8O8tgb9pupjeQ==", - "dependencies": { - "d3-color": "1 - 2" - } - }, - "node_modules/d3-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-2.0.0.tgz", - "integrity": "sha512-ZwZQxKhBnv9yHaiWd6ZU4x5BtCQ7pXszEV9CU6kRgwIQVQGLMv1oiL4M+MK/n79sYzsj+gcgpPQSctJUsLN7fA==" - }, - "node_modules/d3-polygon": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-2.0.0.tgz", - "integrity": "sha512-MsexrCK38cTGermELs0cO1d79DcTsQRN7IWMJKczD/2kBjzNXxLUWP33qRF6VDpiLV/4EI4r6Gs0DAWQkE8pSQ==" - }, - "node_modules/d3-quadtree": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-2.0.0.tgz", - "integrity": "sha512-b0Ed2t1UUalJpc3qXzKi+cPGxeXRr4KU9YSlocN74aTzp6R/Ud43t79yLLqxHRWZfsvWXmbDWPpoENK1K539xw==" - }, - "node_modules/d3-random": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/d3-random/-/d3-random-2.2.2.tgz", - "integrity": "sha512-0D9P8TRj6qDAtHhRQn6EfdOtHMfsUWanl3yb/84C4DqpZ+VsgfI5iTVRNRbELCfNvRfpMr8OrqqUTQ6ANGCijw==" - }, - "node_modules/d3-scale": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-3.3.0.tgz", - "integrity": "sha512-1JGp44NQCt5d1g+Yy+GeOnZP7xHo0ii8zsQp6PGzd+C1/dl0KGsp9A7Mxwp+1D1o4unbTTxVdU/ZOIEBoeZPbQ==", - "dependencies": { - "d3-array": "^2.3.0", - "d3-format": "1 - 2", - "d3-interpolate": "1.2.0 - 2", - "d3-time": "^2.1.1", - "d3-time-format": "2 - 3" - } - }, - "node_modules/d3-scale-chromatic": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-2.0.0.tgz", - "integrity": "sha512-LLqy7dJSL8yDy7NRmf6xSlsFZ6zYvJ4BcWFE4zBrOPnQERv9zj24ohnXKRbyi9YHnYV+HN1oEO3iFK971/gkzA==", - "dependencies": { - "d3-color": "1 - 2", - "d3-interpolate": "1 - 2" - } - }, - "node_modules/d3-selection": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-2.0.0.tgz", - "integrity": "sha512-XoGGqhLUN/W14NmaqcO/bb1nqjDAw5WtSYb2X8wiuQWvSZUsUVYsOSkOybUrNvcBjaywBdYPy03eXHMXjk9nZA==" - }, - "node_modules/d3-shape": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-2.1.0.tgz", - "integrity": "sha512-PnjUqfM2PpskbSLTJvAzp2Wv4CZsnAgTfcVRTwW03QR3MkXF8Uo7B1y/lWkAsmbKwuecto++4NlsYcvYpXpTHA==", - "dependencies": { - "d3-path": "1 - 2" - } - }, - "node_modules/d3-time": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-2.1.1.tgz", - "integrity": "sha512-/eIQe/eR4kCQwq7yxi7z4c6qEXf2IYGcjoWB5OOQy4Tq9Uv39/947qlDcN2TLkiTzQWzvnsuYPB9TrWaNfipKQ==", - "dependencies": { - "d3-array": "2" - } - }, - "node_modules/d3-time-format": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-3.0.0.tgz", - "integrity": "sha512-UXJh6EKsHBTjopVqZBhFysQcoXSv/5yLONZvkQ5Kk3qbwiUYkdX17Xa1PT6U1ZWXGGfB1ey5L8dKMlFq2DO0Ag==", - "dependencies": { - "d3-time": "1 - 2" - } - }, - "node_modules/d3-timer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-2.0.0.tgz", - "integrity": "sha512-TO4VLh0/420Y/9dO3+f9abDEFYeCUr2WZRlxJvbp4HPTQcSylXNiL6yZa9FIUvV1yRiFufl1bszTCLDqv9PWNA==" - }, - "node_modules/d3-transition": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-2.0.0.tgz", - "integrity": "sha512-42ltAGgJesfQE3u9LuuBHNbGrI/AJjNL2OAUdclE70UE6Vy239GCBEYD38uBPoLeNsOhFStGpPI0BAOV+HMxog==", - "dependencies": { - "d3-color": "1 - 2", - "d3-dispatch": "1 - 2", - "d3-ease": "1 - 2", - "d3-interpolate": "1 - 2", - "d3-timer": "1 - 2" - }, - "peerDependencies": { - "d3-selection": "2" - } - }, - "node_modules/d3-zoom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-2.0.0.tgz", - "integrity": "sha512-fFg7aoaEm9/jf+qfstak0IYpnesZLiMX6GZvXtUSdv8RH2o4E2qeelgdU09eKS6wGuiGMfcnMI0nTIqWzRHGpw==", - "dependencies": { - "d3-dispatch": "1 - 2", - "d3-drag": "2", - "d3-interpolate": "1 - 2", - "d3-selection": "2", - "d3-transition": "2" - } - }, - "node_modules/delaunator": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-4.0.1.tgz", - "integrity": "sha512-WNPWi1IRKZfCt/qIDMfERkDp93+iZEmOxN2yy4Jg+Xhv8SLk2UTqqbe1sfiipn0and9QrE914/ihdx82Y/Giag==" - }, "node_modules/emoji-regex": { "version": "10.3.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz", @@ -718,22 +430,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/internmap": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/internmap/-/internmap-1.0.1.tgz", - "integrity": "sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==" - }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -891,16 +587,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/rw": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", - "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==" - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, "node_modules/signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", diff --git a/src/inboundHttp.ts b/src/inboundHttp.ts index 96771453..fbaaac57 100644 --- a/src/inboundHttp.ts +++ b/src/inboundHttp.ts @@ -6,7 +6,7 @@ export class ResponseBuilder { private hasWrittenHeaders: boolean = false; private hasSentResponse: boolean = false; private resolveFunction: ResolveFunction; - private streamController: any; + private internalWriter: WritableStreamDefaultWriter | undefined; constructor(resolve: ResolveFunction) { this.resolveFunction = resolve; @@ -43,59 +43,57 @@ export class ResponseBuilder { } return this; } - send(value: BodyInit = new Uint8Array()) { + send(value: BodyInit | null) { if (this.hasSentResponse) { throw new Error('Response has already been sent'); } + // If headers have not already been sent, Set the value on the engine and + // let it take care of setting content type/length headers if (!this.hasWrittenHeaders) { this.resolveFunction( new Response(value, { headers: this.headers, status: this.statusCode }), ); this.hasWrittenHeaders = true; } else { - this.write(value); + // If headers have been sent already, it is a streaming response, continue + // writing to Readable stream + if (value) { + this.write(value); + } + this.end(); } - this.end(); this.hasSentResponse = true; } write(value: BodyInit) { if (this.hasSentResponse) { throw new Error('Response has already been sent'); } + let contents = convertToUint8Array(value); if (!this.hasWrittenHeaders) { - let temp; - let readableStream = new ReadableStream({ - start(controller) { - controller.enqueue(convertToUint8Array(value)); - let streamController = { - pump: (value: BodyInit) => { - controller.enqueue(convertToUint8Array(value)); - }, - close: () => { - controller.close(); - }, - }; - temp = streamController; - }, - }); - this.streamController = temp; + let { readable, writable } = new TransformStream(); + this.internalWriter = writable.getWriter(); this.resolveFunction( - new Response(readableStream, { + new Response(readable, { headers: this.headers, status: this.statusCode, }), ); - this.hasWrittenHeaders = true; - return; } - this.streamController.pump(convertToUint8Array(value)); + this.internalWriter!.write(contents); + this.hasWrittenHeaders = true; + return; } end() { if (this.hasSentResponse) { throw new Error('Response has already been sent'); } + if (!this.internalWriter) { + throw new Error( + '`res.end()` called before `res.write()` - Consider using `res.send()` instead', + ); + } // close stream - this.streamController.close(); + this.internalWriter!.close(); this.hasSentResponse = true; } } From 8b7b733fac0fac023e56061ffafe38224f7d7937 Mon Sep 17 00:00:00 2001 From: karthik2804 Date: Mon, 17 Jun 2024 11:35:03 +0200 Subject: [PATCH 6/7] more cleanups Signed-off-by: karthik2804 --- README.md | 6 +++--- src/inboundHttp.ts | 9 ++++----- templates/http-ts/content/package.json | 2 +- templates/http-ts/content/src/index.ts | 6 +++--- templates/http-ts/content/src/spin.ts | 6 +++--- 5 files changed, 14 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 98a49222..a6b8431a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Spin JS SDK -This is an SDK for Javascript and Typescript based on [componentize-js](https://github.com/bytecodealliance/ComponentizeJS). +This is an SDK for Javascript and Typescript based on [ComponentizeJS](https://github.com/bytecodealliance/ComponentizeJS). ## Installing the templates @@ -13,7 +13,7 @@ The templates can be installed with the following command: spin plugin install --update --git https://github.com/fermyon/spin-js-sdk --branch feat/sdk-v2 ``` -## Creating and Building a new app= +## Creating and building a new app ```bash spin new -t http-ts hello-world -a @@ -30,7 +30,7 @@ spin up ## Note: Installing the package -Currently pre-release versionf are published on NPM and can be installed using the following command: +Currently pre-release versions are published on NPM and can be installed using the following command: ```bash npm install @fermyon/spin-sdk@next diff --git a/src/inboundHttp.ts b/src/inboundHttp.ts index fbaaac57..e6880401 100644 --- a/src/inboundHttp.ts +++ b/src/inboundHttp.ts @@ -43,7 +43,7 @@ export class ResponseBuilder { } return this; } - send(value: BodyInit | null) { + send(value?: BodyInit) { if (this.hasSentResponse) { throw new Error('Response has already been sent'); } @@ -78,19 +78,18 @@ export class ResponseBuilder { status: this.statusCode, }), ); + this.hasWrittenHeaders = true; } this.internalWriter!.write(contents); - this.hasWrittenHeaders = true; return; } end() { if (this.hasSentResponse) { throw new Error('Response has already been sent'); } + // Not a streaming response, use 'send()' directly to send reponse. if (!this.internalWriter) { - throw new Error( - '`res.end()` called before `res.write()` - Consider using `res.send()` instead', - ); + this.send(); } // close stream this.internalWriter!.close(); diff --git a/templates/http-ts/content/package.json b/templates/http-ts/content/package.json index fb5f121e..3bb49f16 100644 --- a/templates/http-ts/content/package.json +++ b/templates/http-ts/content/package.json @@ -20,4 +20,4 @@ "dependencies": { "@fermyon/spin-sdk": "^2.0.0-alpha.2" } -} \ No newline at end of file +} diff --git a/templates/http-ts/content/src/index.ts b/templates/http-ts/content/src/index.ts index c560a3cb..61144ef2 100644 --- a/templates/http-ts/content/src/index.ts +++ b/templates/http-ts/content/src/index.ts @@ -1,6 +1,6 @@ import { ResponseBuilder } from "@fermyon/spin-sdk"; export async function handler(req: Request, res: ResponseBuilder) { - console.log(req) - res.send("hello universe") -} \ No newline at end of file + console.log(req); + res.send("hello universe"); +} diff --git a/templates/http-ts/content/src/spin.ts b/templates/http-ts/content/src/spin.ts index c97c3e50..204d914e 100644 --- a/templates/http-ts/content/src/spin.ts +++ b/templates/http-ts/content/src/spin.ts @@ -3,7 +3,7 @@ import { handler } from "."; //@ts-ignore addEventListener('fetch', (event: FetchEvent) => { - handleEvent(event) + handleEvent(event); }); async function handleEvent(event: FetchEvent) { @@ -16,7 +16,7 @@ async function handleEvent(event: FetchEvent) { //@ts-ignore event.respondWith(responsePromise); - let res = new ResponseBuilder(resolve) + let res = new ResponseBuilder(resolve); await handler(event.request, res) } @@ -25,4 +25,4 @@ async function handleEvent(event: FetchEvent) { // oncehttps://github.com/bytecodealliance/ComponentizeJS/issues/114 is resolved export const incomingHandler = { handle() { } -} \ No newline at end of file +} From 86eff5bac64da7b6d96c7f9d0f01003a9d4f7d7c Mon Sep 17 00:00:00 2001 From: karthik2804 Date: Mon, 17 Jun 2024 15:02:53 +0200 Subject: [PATCH 7/7] update tests to use local lib Signed-off-by: karthik2804 --- test/test-app/package-lock.json | 128 +++++++++++++++++++++++++------- test/test-app/package.json | 2 +- test/test-app/src/index.ts | 4 +- test/test-app/src/spin.ts | 30 ++++++-- test/test-app/src/test.ts | 6 +- test/test-app/tsconfig.json | 3 +- 6 files changed, 132 insertions(+), 41 deletions(-) diff --git a/test/test-app/package-lock.json b/test/test-app/package-lock.json index 29a8dd37..63f8cf80 100644 --- a/test/test-app/package-lock.json +++ b/test/test-app/package-lock.json @@ -9,7 +9,7 @@ "version": "1.0.0", "license": "ISC", "dependencies": { - "@fermyon/spin-sdk": "^2.0.0-alpha.1" + "@fermyon/spin-sdk": "file:../../" }, "devDependencies": { "@bytecodealliance/componentize-js": "^0.8.3", @@ -21,10 +21,28 @@ "yargs": "^17.7.2" } }, + "../..": { + "name": "@fermyon/spin-sdk", + "version": "2.0.0-alpha.2", + "license": "Apache-2.0", + "dependencies": { + "@bytecodealliance/componentize-js": "https://github.com/fermyon/ComponentizeJS#use_fetch_event", + "itty-router": "^3.0.12", + "yargs": "^17.7.2" + }, + "bin": { + "j2w": "bin/j2w.mjs" + }, + "devDependencies": { + "prettier": "^3.2.5", + "typescript": "^5.4.3" + } + }, "node_modules/@bytecodealliance/componentize-js": { "version": "0.8.3", "resolved": "https://registry.npmjs.org/@bytecodealliance/componentize-js/-/componentize-js-0.8.3.tgz", "integrity": "sha512-QyEHRtVg/Cg6RsA75AvRSbSOr0u+FLuXqB89X4Sys44K/VT5g/S9eMn8gqTotfuXVU3btS3Z4QAiyHSF2bja3w==", + "dev": true, "workspaces": [ "." ], @@ -38,6 +56,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/@bytecodealliance/jco/-/jco-1.1.1.tgz", "integrity": "sha512-s8Zz6GFPlo2g+dsGp1OMIWXSZnM4FyIloxNAc4grF5TZwFoD00Gj8b0xvpmFSeZj36X/bJPa7x3za3j7Cfeetw==", + "dev": true, "workspaces": [ "packages/preview2-shim" ], @@ -57,12 +76,14 @@ "node_modules/@bytecodealliance/preview2-shim": { "version": "0.16.2", "resolved": "https://registry.npmjs.org/@bytecodealliance/preview2-shim/-/preview2-shim-0.16.2.tgz", - "integrity": "sha512-36MwesmbLSf3Y5/OHcS85iBaF0N92CQ4gpjtDVKSbrjxmrBKCWlWVfoQ03F/cqDg8k5K7pzVaVBH0XBIbTCfTQ==" + "integrity": "sha512-36MwesmbLSf3Y5/OHcS85iBaF0N92CQ4gpjtDVKSbrjxmrBKCWlWVfoQ03F/cqDg8k5K7pzVaVBH0XBIbTCfTQ==", + "dev": true }, "node_modules/@bytecodealliance/wizer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/@bytecodealliance/wizer/-/wizer-3.0.1.tgz", "integrity": "sha512-f0NBiBHCNBkbFHTPRbA7aKf/t4KyNhi2KvSqw3QzCgi8wFF/uLZ0dhejj93rbiKO/iwWbmU7v9K3SVkW81mcjQ==", + "dev": true, "bin": { "wizer": "wizer.js" }, @@ -85,6 +106,7 @@ "cpu": [ "arm64" ], + "dev": true, "optional": true, "os": [ "darwin" @@ -100,6 +122,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "darwin" @@ -115,6 +138,7 @@ "cpu": [ "arm64" ], + "dev": true, "optional": true, "os": [ "linux" @@ -130,6 +154,7 @@ "cpu": [ "s390x" ], + "dev": true, "optional": true, "os": [ "linux" @@ -145,6 +170,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "linux" @@ -160,6 +186,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "win32" @@ -178,22 +205,14 @@ } }, "node_modules/@fermyon/spin-sdk": { - "version": "2.0.0-alpha.1", - "resolved": "https://registry.npmjs.org/@fermyon/spin-sdk/-/spin-sdk-2.0.0-alpha.1.tgz", - "integrity": "sha512-XKLUDgWQfbPYpxVdWjwN1K5nXJVK9KR9G3zfm2VDA8u4QUAWpWXd0PzoHZrrkMDCfTtRUBmyTBJfCoosFZ92hA==", - "dependencies": { - "@bytecodealliance/componentize-js": "^0.8.3", - "itty-router": "^3.0.12", - "yargs": "^17.7.2" - }, - "bin": { - "j2w": "bin/j2w.mjs" - } + "resolved": "../..", + "link": true }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.5", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "dev": true, "dependencies": { "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", @@ -207,6 +226,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, "engines": { "node": ">=6.0.0" } @@ -215,6 +235,7 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "dev": true, "engines": { "node": ">=6.0.0" } @@ -223,6 +244,7 @@ "version": "0.3.6", "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", + "dev": true, "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25" @@ -231,12 +253,14 @@ "node_modules/@jridgewell/sourcemap-codec": { "version": "1.4.15", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.25", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" @@ -481,6 +505,7 @@ "version": "8.11.3", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "dev": true, "bin": { "acorn": "bin/acorn" }, @@ -526,6 +551,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, "engines": { "node": ">=12" }, @@ -537,6 +563,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -551,6 +578,7 @@ "version": "116.0.0", "resolved": "https://registry.npmjs.org/binaryen/-/binaryen-116.0.0.tgz", "integrity": "sha512-Hp0dXC6Cb/rTwWEoUS2BRghObE7g/S9umKtxuTDt3f61G6fNTE/YVew/ezyy3IdHcLx3f17qfh6LwETgCfvWkQ==", + "dev": true, "bin": { "wasm-opt": "bin/wasm-opt", "wasm2js": "bin/wasm2js" @@ -603,7 +631,8 @@ "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true }, "node_modules/caniuse-lite": { "version": "1.0.30001618", @@ -629,6 +658,7 @@ "version": "5.3.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "dev": true, "engines": { "node": "^12.17.0 || ^14.13 || >=16.0.0" }, @@ -640,6 +670,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/chalk-template/-/chalk-template-1.1.0.tgz", "integrity": "sha512-T2VJbcDuZQ0Tb2EWwSotMPJjgpy1/tGee1BTpUNsGZ/qgNjV2t7Mvu+d4600U564nbLesN1x2dPL+xii174Ekg==", + "dev": true, "dependencies": { "chalk": "^5.2.0" }, @@ -663,6 +694,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==", + "dev": true, "dependencies": { "restore-cursor": "^4.0.0" }, @@ -677,6 +709,7 @@ "version": "2.9.2", "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", + "dev": true, "engines": { "node": ">=6" }, @@ -688,6 +721,7 @@ "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", @@ -701,6 +735,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, "engines": { "node": ">=8" } @@ -708,12 +743,14 @@ "node_modules/cliui/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true }, "node_modules/cliui/node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -727,6 +764,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, "dependencies": { "ansi-regex": "^5.0.1" }, @@ -752,6 +790,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, "dependencies": { "color-name": "~1.1.4" }, @@ -762,7 +801,8 @@ "node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, "node_modules/colorette": { "version": "2.0.20", @@ -774,6 +814,7 @@ "version": "12.0.0", "resolved": "https://registry.npmjs.org/commander/-/commander-12.0.0.tgz", "integrity": "sha512-MwVNWlYjDTtOjX5PiD7o5pK0UrFU/OYgcJfjjK4RaHZETNtjJqrZa9Y9ds88+A+f+d5lv+561eZ+yCKoS3gbAA==", + "dev": true, "engines": { "node": ">=18" } @@ -801,7 +842,8 @@ "node_modules/emoji-regex": { "version": "10.3.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz", - "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==" + "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==", + "dev": true }, "node_modules/enhanced-resolve": { "version": "5.16.1", @@ -831,12 +873,14 @@ "node_modules/es-module-lexer": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.2.tgz", - "integrity": "sha512-l60ETUTmLqbVbVHv1J4/qj+M8nq7AwMzEcg3kmJDt9dCNrTk+yHcYFf/Kw75pMDwd9mPcIGCG5LcS20SxYRzFA==" + "integrity": "sha512-l60ETUTmLqbVbVHv1J4/qj+M8nq7AwMzEcg3kmJDt9dCNrTk+yHcYFf/Kw75pMDwd9mPcIGCG5LcS20SxYRzFA==", + "dev": true }, "node_modules/escalade": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "dev": true, "engines": { "node": ">=6" } @@ -961,6 +1005,7 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, "engines": { "node": "6.* || 8.* || >= 10.*" } @@ -969,6 +1014,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.2.0.tgz", "integrity": "sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==", + "dev": true, "engines": { "node": ">=18" }, @@ -1053,6 +1099,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, "engines": { "node": ">=8" } @@ -1061,6 +1108,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-2.0.0.tgz", "integrity": "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==", + "dev": true, "engines": { "node": ">=12" }, @@ -1093,6 +1141,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.0.0.tgz", "integrity": "sha512-FRdAyx5lusK1iHG0TWpVtk9+1i+GjrzRffhDg4ovQ7mcidMQ6mj+MhKPmvh7Xwyv5gIS06ns49CA7Sqg7lC22Q==", + "dev": true, "engines": { "node": ">=18" }, @@ -1115,11 +1164,6 @@ "node": ">=0.10.0" } }, - "node_modules/itty-router": { - "version": "3.0.12", - "resolved": "https://registry.npmjs.org/itty-router/-/itty-router-3.0.12.tgz", - "integrity": "sha512-s98XTPhle6GGbaFf0kYrOD3Q8gyhnqvOqkwYijC3AmkceNKqWUp13YHg6dWmqmVv4pP7l7c94XI92I0EXVGO0w==" - }, "node_modules/jest-worker": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", @@ -1180,6 +1224,7 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-6.0.0.tgz", "integrity": "sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw==", + "dev": true, "dependencies": { "chalk": "^5.3.0", "is-unicode-supported": "^1.3.0" @@ -1195,6 +1240,7 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz", "integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==", + "dev": true, "engines": { "node": ">=12" }, @@ -1246,6 +1292,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, "engines": { "node": ">=6" } @@ -1254,6 +1301,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", + "dev": true, "bin": { "mkdirp": "dist/cjs/src/bin.js" }, @@ -1280,6 +1328,7 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, "dependencies": { "mimic-fn": "^2.1.0" }, @@ -1294,6 +1343,7 @@ "version": "8.0.1", "resolved": "https://registry.npmjs.org/ora/-/ora-8.0.1.tgz", "integrity": "sha512-ANIvzobt1rls2BDny5fWZ3ZVKyD6nscLvfFRpQgfWsythlcsVUC9kL0zq6j2Z5z9wwp1kd7wpsD/T9qNPVLCaQ==", + "dev": true, "dependencies": { "chalk": "^5.3.0", "cli-cursor": "^4.0.0", @@ -1436,6 +1486,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -1482,6 +1533,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==", + "dev": true, "dependencies": { "onetime": "^5.1.0", "signal-exit": "^3.0.2" @@ -1588,12 +1640,14 @@ "node_modules/signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true }, "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -1602,6 +1656,7 @@ "version": "0.5.21", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" @@ -1611,6 +1666,7 @@ "version": "0.2.2", "resolved": "https://registry.npmjs.org/stdin-discarder/-/stdin-discarder-0.2.2.tgz", "integrity": "sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ==", + "dev": true, "engines": { "node": ">=18" }, @@ -1622,6 +1678,7 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.1.0.tgz", "integrity": "sha512-SEIJCWiX7Kg4c129n48aDRwLbFb2LJmXXFrWBG4NGaRtMQ3myKPKbwrD1BKqQn74oCoNMBVrfDEr5M9YxCsrkw==", + "dev": true, "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", @@ -1638,6 +1695,7 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, "dependencies": { "ansi-regex": "^6.0.1" }, @@ -1688,6 +1746,7 @@ "version": "5.31.0", "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.0.tgz", "integrity": "sha512-Q1JFAoUKE5IMfI4Z/lkE/E6+SwgzO+x4tq4v1AyBLRj8VSYvRO6A/rQrPg1yud4g0En9EKI1TvFRF2tQFcoUkg==", + "dev": true, "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.8.2", @@ -1738,7 +1797,8 @@ "node_modules/terser/node_modules/commander": { "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true }, "node_modules/to-regex-range": { "version": "5.0.1", @@ -2031,6 +2091,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -2047,6 +2108,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, "engines": { "node": ">=8" } @@ -2054,12 +2116,14 @@ "node_modules/wrap-ansi/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true }, "node_modules/wrap-ansi/node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -2073,6 +2137,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, "dependencies": { "ansi-regex": "^5.0.1" }, @@ -2084,6 +2149,7 @@ "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, "engines": { "node": ">=10" } @@ -2092,6 +2158,7 @@ "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", @@ -2109,6 +2176,7 @@ "version": "21.1.1", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, "engines": { "node": ">=12" } @@ -2117,6 +2185,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, "engines": { "node": ">=8" } @@ -2124,12 +2193,14 @@ "node_modules/yargs/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true }, "node_modules/yargs/node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -2143,6 +2214,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, "dependencies": { "ansi-regex": "^5.0.1" }, diff --git a/test/test-app/package.json b/test/test-app/package.json index 9d3a5cc4..1babd022 100644 --- a/test/test-app/package.json +++ b/test/test-app/package.json @@ -20,6 +20,6 @@ "yargs": "^17.7.2" }, "dependencies": { - "@fermyon/spin-sdk": "^2.0.0-alpha.1" + "@fermyon/spin-sdk": "file:../../" } } \ No newline at end of file diff --git a/test/test-app/src/index.ts b/test/test-app/src/index.ts index a5e46e5e..873d0a05 100644 --- a/test/test-app/src/index.ts +++ b/test/test-app/src/index.ts @@ -1,4 +1,4 @@ -import { HttpRequest, ResponseBuilder, Router } from "@fermyon/spin-sdk"; +import { ResponseBuilder, Router } from "@fermyon/spin-sdk"; import { testFunctionality, health } from "./test"; let router = Router() @@ -6,6 +6,6 @@ let router = Router() router.get("/", async (_, req, res) => { await testFunctionality(req, res) }) router.get("/health", async (_, req, res) => { await health(req, res) }) -export async function handler(req: HttpRequest, res: ResponseBuilder) { +export async function handler(req: Request, res: ResponseBuilder) { await router.handleRequest(req, res) } diff --git a/test/test-app/src/spin.ts b/test/test-app/src/spin.ts index 609ed478..f757f021 100644 --- a/test/test-app/src/spin.ts +++ b/test/test-app/src/spin.ts @@ -1,10 +1,28 @@ -import { HttpHandler, HttpRequest, ResponseBuilder } from "@fermyon/spin-sdk"; +import { ResponseBuilder } from "@fermyon/spin-sdk"; import { handler } from "."; -class App extends HttpHandler { - handleRequest(req: HttpRequest, res: ResponseBuilder): Promise { - return handler(req, res) - } +//@ts-ignore +addEventListener('fetch', (event: FetchEvent) => { + handleEvent(event); +}); + +async function handleEvent(event: FetchEvent) { + + let resolve: any, reject: any; + let responsePromise = new Promise(async (res, rej) => { + resolve = res; + reject = rej; + }); + //@ts-ignore + event.respondWith(responsePromise); + + let res = new ResponseBuilder(resolve); + + await handler(event.request, res) } -export const incomingHandler = new App() +// Keep wizer happy during pre-init. Should go away +// oncehttps://github.com/bytecodealliance/ComponentizeJS/issues/114 is resolved +export const incomingHandler = { + handle() { } +} \ No newline at end of file diff --git a/test/test-app/src/test.ts b/test/test-app/src/test.ts index 5237b482..5d78ec7a 100644 --- a/test/test-app/src/test.ts +++ b/test/test-app/src/test.ts @@ -1,14 +1,14 @@ -import { HttpRequest, ResponseBuilder } from "@fermyon/spin-sdk"; +import { ResponseBuilder } from "@fermyon/spin-sdk"; const encoder = new TextEncoder() const decoder = new TextDecoder() -function health(req: HttpRequest, res: ResponseBuilder) { +function health(req: Request, res: ResponseBuilder) { res.status(200) res.send("Server is healthy") } -async function testFunctionality(req: HttpRequest, res: ResponseBuilder) { +async function testFunctionality(req: Request, res: ResponseBuilder) { //TODO: Add tests once fetch is available res.status(200) res.send("test completed successfully") diff --git a/test/test-app/tsconfig.json b/test/test-app/tsconfig.json index 8d86d98b..851fe99f 100644 --- a/test/test-app/tsconfig.json +++ b/test/test-app/tsconfig.json @@ -7,7 +7,8 @@ "jsx": "react", "skipLibCheck": true, "lib": [ - "ES2015" + "ES2015", + "WebWorker" ], "allowJs": true, "strict": true,