init
This commit is contained in:
commit
99d8b08683
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"typescript.tsdk": "node_modules\\typescript\\lib"
|
||||
}
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
export declare function undef<A>(): A | undefined;
|
||||
export declare function memoize<A>(fn: () => A): () => A;
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.memoize = exports.undef = void 0;
|
||||
function undef() {
|
||||
return undefined;
|
||||
}
|
||||
exports.undef = undef;
|
||||
function memoize(fn) {
|
||||
let memo;
|
||||
return () => {
|
||||
if (memo === undefined) {
|
||||
memo = fn();
|
||||
}
|
||||
return memo;
|
||||
};
|
||||
}
|
||||
exports.memoize = memoize;
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
import { ContentType, Message, MessageFromClient, CreateMailboxResponse, KeyValPair, MessageEnvelope, SendReceipt } from "./proto/wsmessages";
|
||||
export interface ContentTypeHandler {
|
||||
readonly webSocketUrlPath: string;
|
||||
sendMessageFromClient(mfc: MessageFromClient, ws: WebSocket): void;
|
||||
}
|
||||
export declare const ContentTypeHandler: {
|
||||
Json: ContentTypeHandler;
|
||||
Protobuf: ContentTypeHandler;
|
||||
};
|
||||
export declare function newHermesClient(rootUrl: string, contentTypeHandler: ContentTypeHandler): HermesClient;
|
||||
export interface ChangeDataCaptureEvent {
|
||||
id: string;
|
||||
schema: string;
|
||||
table: string;
|
||||
action: string;
|
||||
data: any;
|
||||
commitTime: string;
|
||||
}
|
||||
interface RawRpcRequest {
|
||||
to: string;
|
||||
endPoint: string;
|
||||
body?: Uint8Array;
|
||||
contentType?: ContentType;
|
||||
headers?: KeyValPair[];
|
||||
state?: Uint8Array;
|
||||
}
|
||||
export declare class RpcRequestResponse {
|
||||
correlationId: string;
|
||||
sendReceiptEnvelope: MessageEnvelope | undefined;
|
||||
sendReceipt: SendReceipt | undefined;
|
||||
sentMessage: Message | undefined;
|
||||
inboxEnvelope: MessageEnvelope | undefined;
|
||||
inboxMessage: Message | undefined;
|
||||
constructor(correlationId: string);
|
||||
role(): string | undefined;
|
||||
contentType(): ContentType;
|
||||
isProtobuf(): boolean;
|
||||
isJson(): boolean;
|
||||
isClient(): boolean | undefined;
|
||||
hasRequestAndResponse(): boolean;
|
||||
timeStarted(): Date | undefined;
|
||||
timeStartedL(): number | undefined;
|
||||
timeCompleted(): Date | undefined;
|
||||
durationInMillis(): number | undefined;
|
||||
endPoint(): string | undefined;
|
||||
requestMessage(): Message | undefined;
|
||||
requestEnvelope(): MessageEnvelope | undefined;
|
||||
responseMessage(): Message | undefined;
|
||||
responseEnvelope(): MessageEnvelope | undefined;
|
||||
status(): string;
|
||||
processSchema(reqOrResp: "request" | "response", data?: Uint8Array): Promise<any>;
|
||||
responseObj(): Promise<any>;
|
||||
requestObj(): Promise<any>;
|
||||
}
|
||||
declare const GlobalClient: {
|
||||
get: () => HermesClient;
|
||||
};
|
||||
export default GlobalClient;
|
||||
export declare function runHermesClientTest(): void;
|
||||
export declare function runHermesClientTest2(): void;
|
||||
export interface CdcSubscription {
|
||||
tables: CdcTable[];
|
||||
startSeq?: string;
|
||||
}
|
||||
export interface CdcTable {
|
||||
database: string;
|
||||
table: string;
|
||||
}
|
||||
export interface HermesClient {
|
||||
readonly rootUrl: string;
|
||||
mailbox(): Promise<CreateMailboxResponse>;
|
||||
rawRpcCall(request: RawRpcRequest): Promise<Message>;
|
||||
cdcSubscribe<A>(cdcs: CdcSubscription, listener: (cdcEvent: ChangeDataCaptureEvent, a: A) => void): void;
|
||||
rpcObserverSubscribe(readerKey: string, listener: (correlation: RpcRequestResponse) => void): void;
|
||||
}
|
||||
|
|
@ -0,0 +1,689 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.runHermesClientTest2 = exports.runHermesClientTest = exports.RpcRequestResponse = exports.newHermesClient = exports.ContentTypeHandler = void 0;
|
||||
const wsmessages_1 = require("./proto/wsmessages");
|
||||
const Utils_1 = require("../Utils");
|
||||
const JsonContentTypeHandler = {
|
||||
webSocketUrlPath: "/api/ws/send_receive_json",
|
||||
sendMessageFromClient(mfc, ws) {
|
||||
const obj = wsmessages_1.MessageFromClient.toJSON(mfc);
|
||||
const jsonStr = JSON.stringify(obj);
|
||||
ws.send(jsonStr);
|
||||
}
|
||||
};
|
||||
const ProtobufContentTypeHandler = {
|
||||
webSocketUrlPath: "/api/ws/send_receive_proto",
|
||||
sendMessageFromClient(mfc, ws) {
|
||||
const bytes = wsmessages_1.MessageFromClient.encode(mfc).finish();
|
||||
ws.send(bytes);
|
||||
}
|
||||
};
|
||||
exports.ContentTypeHandler = {
|
||||
Json: JsonContentTypeHandler,
|
||||
Protobuf: ProtobufContentTypeHandler,
|
||||
};
|
||||
function newHermesClient(rootUrl, contentTypeHandler) {
|
||||
const hci = new HermesClientImpl(rootUrl, contentTypeHandler);
|
||||
hci.mailbox().then((mbox) => {
|
||||
const correlations = hci.correlations;
|
||||
hci.channelMessageSubscribe({
|
||||
id: "rpc-inbox",
|
||||
state: "rpc-inbox",
|
||||
readerKey: mbox.readerKey,
|
||||
channel: "rpc-inbox",
|
||||
startSeq: "all"
|
||||
}, (me, msg) => {
|
||||
var _a, _b, _c, _d, _e, _f;
|
||||
if (me.messageBytes) {
|
||||
try {
|
||||
const msg = wsmessages_1.Message.decode(me.messageBytes);
|
||||
const endPoint = (_b = (_a = msg.header) === null || _a === void 0 ? void 0 : _a.rpcHeader) === null || _b === void 0 ? void 0 : _b.endPoint;
|
||||
if (((_d = (_c = msg.header) === null || _c === void 0 ? void 0 : _c.rpcHeader) === null || _d === void 0 ? void 0 : _d.frameType) === wsmessages_1.RpcFrameType.Request && endPoint == "ping") {
|
||||
hci.sendPongResponse(mbox, msg, endPoint);
|
||||
}
|
||||
else {
|
||||
const correlationId = (_f = (_e = msg.header) === null || _e === void 0 ? void 0 : _e.rpcHeader) === null || _f === void 0 ? void 0 : _f.correlationId;
|
||||
if (correlationId) {
|
||||
const resolve = correlations.get(correlationId);
|
||||
if (resolve !== undefined) {
|
||||
resolve(msg);
|
||||
}
|
||||
correlations.delete(correlationId);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
console.error("error decoding message", e);
|
||||
}
|
||||
}
|
||||
// noop since we are only interested in the correlationId for rpc and that happens in onMessage
|
||||
});
|
||||
});
|
||||
// send ping every 30 seconds
|
||||
setInterval(() => hci.sendPing(), 30 * 1000);
|
||||
return hci;
|
||||
}
|
||||
exports.newHermesClient = newHermesClient;
|
||||
/**
|
||||
* Create the mailbox
|
||||
* @param channels
|
||||
* @param rootUrl
|
||||
* @returns
|
||||
*/
|
||||
async function createMailbox(channels, rootUrl) {
|
||||
const mbox = {
|
||||
channels: channels,
|
||||
privateMetadata: {},
|
||||
publicMetadata: {},
|
||||
purgeTimeoutInMillis: 0,
|
||||
closeTimeoutInMillis: 0,
|
||||
extraData: {},
|
||||
};
|
||||
const mboxObj = wsmessages_1.CreateMailboxRequest.toJSON(mbox);
|
||||
const mboxJson = JSON.stringify(mboxObj);
|
||||
let mailboxResponse = undefined;
|
||||
const response = await fetch(`${rootUrl}/api/create_mailbox`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: mboxJson,
|
||||
});
|
||||
if (response.ok) {
|
||||
const responseJsonStr = await response.text();
|
||||
mailboxResponse = wsmessages_1.CreateMailboxResponse.fromJSON(JSON.parse(responseJsonStr));
|
||||
}
|
||||
else {
|
||||
throw new Error(`createMailbox failed with status ${response.status}`);
|
||||
}
|
||||
return mailboxResponse;
|
||||
}
|
||||
class Constants {
|
||||
}
|
||||
Constants.rpcInboxChannelName = "rpc-inbox";
|
||||
Constants.rpcSentChannelName = "rpc-sent";
|
||||
class HermesConnection {
|
||||
constructor(clientImpl, mailbox, webSocket) {
|
||||
this.clientImpl = clientImpl;
|
||||
this.mailbox = mailbox;
|
||||
this.webSocket = webSocket;
|
||||
const self = this;
|
||||
webSocket.onmessage = function (event) {
|
||||
if (event.data instanceof ArrayBuffer) {
|
||||
self.onWebSocketBinaryMessage(event.data);
|
||||
}
|
||||
else {
|
||||
self.onWebSocketTextMessage(event.data);
|
||||
}
|
||||
};
|
||||
webSocket.onclose = function (event) {
|
||||
console.log("HermesConnection websocket closed", event);
|
||||
clientImpl.reconnect();
|
||||
};
|
||||
// resend un ack'ed messages
|
||||
clientImpl.sentMessagesWaitingForAck.forEach((smr, idempotentId) => {
|
||||
self.sendSendMessageRequest(smr, false);
|
||||
});
|
||||
}
|
||||
onWebSocketTextMessage(message) {
|
||||
const jsonObj = JSON.parse(message);
|
||||
const m2c = wsmessages_1.MessageToClient.fromJSON(jsonObj);
|
||||
this.onMessageToClient(m2c);
|
||||
}
|
||||
onWebSocketBinaryMessage(message) {
|
||||
const m2c = wsmessages_1.MessageToClient.decode(new Uint8Array(message));
|
||||
this.onMessageToClient(m2c);
|
||||
}
|
||||
onMessageToClient(m2c) {
|
||||
var _a, _b, _c;
|
||||
if (m2c.notification !== undefined) {
|
||||
console.log("hermes client received notification " + m2c.notification, m2c.notification);
|
||||
}
|
||||
else if (m2c.messageEnvelope !== undefined) {
|
||||
const me = m2c.messageEnvelope;
|
||||
if (me.messageBytes === undefined) {
|
||||
console.log("hermes client received empty messageEnvelope", m2c.messageEnvelope);
|
||||
}
|
||||
else {
|
||||
const subscriptionId = (_a = me.serverEnvelope) === null || _a === void 0 ? void 0 : _a.subscriptionId;
|
||||
if (subscriptionId) {
|
||||
const activeSub = this.clientImpl.activeSubscriptions.get(subscriptionId);
|
||||
if (activeSub) {
|
||||
const startSeq = (_b = me.serverEnvelope) === null || _b === void 0 ? void 0 : _b.sequence;
|
||||
if (startSeq) {
|
||||
activeSub.protoRawSubscription.startSeq = String(startSeq);
|
||||
}
|
||||
activeSub.onMessageEvent(me);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (m2c.sendMessageResponse !== undefined) {
|
||||
const id = (_c = m2c.sendMessageResponse) === null || _c === void 0 ? void 0 : _c.idempotentId;
|
||||
if (id) {
|
||||
this.clientImpl.sentMessagesWaitingForAck.delete(id);
|
||||
}
|
||||
console.log("hermes client received SendMessageResponse", m2c.sendMessageResponse);
|
||||
}
|
||||
else if (m2c.subscribeResponse !== undefined) {
|
||||
console.log("hermes client received subscribeResponse", m2c.subscribeResponse);
|
||||
}
|
||||
else if (m2c.ping !== undefined) {
|
||||
this.webSocket.send(JSON.stringify({ pong: {} }));
|
||||
}
|
||||
else if (m2c.pong !== undefined) {
|
||||
console.log("hermes client received pong");
|
||||
}
|
||||
}
|
||||
sendMessageFromClient(mfc) {
|
||||
console.log("sending websocket message", mfc);
|
||||
this.clientImpl.contentTypeHandler.sendMessageFromClient(mfc, this.webSocket);
|
||||
}
|
||||
addActiveSubscription(activeSub) {
|
||||
const listeners = this.clientImpl.activeSubscriptions.get(activeSub.subscriptionId);
|
||||
if (listeners) {
|
||||
throw Error(`subscriptionId ${activeSub.subscriptionId} is already subscribed`);
|
||||
}
|
||||
else {
|
||||
this.clientImpl.activeSubscriptions.set(activeSub.subscriptionId, activeSub);
|
||||
}
|
||||
}
|
||||
cdcSubscribe(cdcs, listener) {
|
||||
const subscriptionId = "cdc-" + cdcs.tables.map((t) => t.database + "." + t.table).join("-");
|
||||
const protoCdcs = {
|
||||
id: subscriptionId,
|
||||
matchers: cdcs.tables,
|
||||
startSeq: cdcs.startSeq,
|
||||
};
|
||||
this.sendMessageFromClient({ subscribeRequest: { subscriptions: [{ changeDataCapture: protoCdcs }] } });
|
||||
function onMessage(msg) {
|
||||
const json = new TextDecoder().decode(msg.messageBytes);
|
||||
const cdcEvent = JSON.parse(json);
|
||||
listener(cdcEvent, cdcEvent.data);
|
||||
}
|
||||
this.addActiveSubscription({
|
||||
subscriptionId: subscriptionId,
|
||||
protoRawSubscription: protoCdcs,
|
||||
onMessageEvent: onMessage,
|
||||
protoSubscription: { changeDataCapture: protoCdcs }
|
||||
});
|
||||
}
|
||||
channelMessageSubscribe(ms, listener) {
|
||||
this.rawChannelSubscribe(ms, wsmessages_1.Message.decode, listener);
|
||||
}
|
||||
channelSendReceiptSubscribe(ms, listener) {
|
||||
this.rawChannelSubscribe(ms, wsmessages_1.SendReceipt.decode, listener);
|
||||
}
|
||||
rawChannelSubscribe(ms, decoder, listener) {
|
||||
const subscriptionId = ms.id;
|
||||
if (!subscriptionId) {
|
||||
throw new Error("MailboxSubscription id is undefined");
|
||||
}
|
||||
function onMessage(msg) {
|
||||
if (msg.messageBytes === undefined) {
|
||||
console.error("MessageEnvelope.messageBytes is undefined");
|
||||
return;
|
||||
}
|
||||
const a = decoder(msg.messageBytes);
|
||||
listener(msg, a);
|
||||
}
|
||||
this.sendMessageFromClient({ subscribeRequest: { subscriptions: [{ mailbox: ms }] } });
|
||||
this.addActiveSubscription({
|
||||
subscriptionId: subscriptionId,
|
||||
onMessageEvent: onMessage,
|
||||
protoRawSubscription: ms,
|
||||
protoSubscription: { mailbox: ms }
|
||||
});
|
||||
}
|
||||
sendPing() {
|
||||
this.sendMessageFromClient({ ping: {} });
|
||||
}
|
||||
sendSendMessageRequest(smr, registerForAck) {
|
||||
if (registerForAck && smr.idempotentId) {
|
||||
this.clientImpl.sentMessagesWaitingForAck.set(smr.idempotentId, smr);
|
||||
}
|
||||
this.sendMessageFromClient({ sendMessageRequest: smr });
|
||||
}
|
||||
rawRpcCall(request) {
|
||||
var _a;
|
||||
const emptyBytes = new Uint8Array(0);
|
||||
const correlationId = ((_a = this.mailbox.address) !== null && _a !== void 0 ? _a : "") + "-" + this.clientImpl.correlationIdCounter++;
|
||||
const idempotentId = this.mailbox.address + correlationId;
|
||||
const smr = {
|
||||
channel: Constants.rpcInboxChannelName,
|
||||
to: [request.to],
|
||||
idempotentId: idempotentId,
|
||||
message: {
|
||||
header: {
|
||||
rpcHeader: {
|
||||
correlationId: correlationId,
|
||||
endPoint: request.endPoint,
|
||||
frameType: wsmessages_1.RpcFrameType.Request,
|
||||
errorInfo: undefined,
|
||||
},
|
||||
sender: this.mailbox.address,
|
||||
contentType: request.contentType,
|
||||
extraHeaders: request.headers,
|
||||
senderSequence: 0,
|
||||
},
|
||||
serverEnvelope: undefined,
|
||||
senderEnvelope: {
|
||||
created: Date.now(),
|
||||
},
|
||||
data: request.body !== undefined ? request.body : emptyBytes,
|
||||
},
|
||||
};
|
||||
const promise = new Promise((resolve, reject) => {
|
||||
this.clientImpl.correlations.set(correlationId, resolve);
|
||||
});
|
||||
this.sendSendMessageRequest(smr, true);
|
||||
return promise;
|
||||
}
|
||||
rpcObserverSubscribe(readerKey, listener) {
|
||||
console.log("rpcObserverSubscribe", readerKey);
|
||||
const correlations = new Map();
|
||||
const msInbox = {
|
||||
id: "rpc-inbox-" + readerKey,
|
||||
readerKey: readerKey,
|
||||
channel: "rpc-inbox",
|
||||
startSeq: "first",
|
||||
};
|
||||
this.channelMessageSubscribe(msInbox, (me, msg) => {
|
||||
var _a, _b;
|
||||
const correlationId = (_b = (_a = msg.header) === null || _a === void 0 ? void 0 : _a.rpcHeader) === null || _b === void 0 ? void 0 : _b.correlationId;
|
||||
if (correlationId) {
|
||||
var correlation = correlations.get(correlationId);
|
||||
if (!correlation) {
|
||||
correlation = new RpcRequestResponse(correlationId);
|
||||
correlations.set(correlationId, correlation);
|
||||
}
|
||||
correlation.inboxEnvelope = me;
|
||||
correlation.inboxMessage = msg;
|
||||
listener(correlation);
|
||||
}
|
||||
});
|
||||
const msSent = {
|
||||
id: "rpc-sent-" + readerKey,
|
||||
readerKey: readerKey,
|
||||
channel: "rpc-sent",
|
||||
startSeq: "first",
|
||||
};
|
||||
this.channelSendReceiptSubscribe(msSent, (me, sr) => {
|
||||
var _a, _b, _c, _d, _e;
|
||||
const msg = (_a = sr.request) === null || _a === void 0 ? void 0 : _a.message;
|
||||
const correlationId = (_e = (_d = (_c = (_b = sr.request) === null || _b === void 0 ? void 0 : _b.message) === null || _c === void 0 ? void 0 : _c.header) === null || _d === void 0 ? void 0 : _d.rpcHeader) === null || _e === void 0 ? void 0 : _e.correlationId;
|
||||
if (correlationId !== undefined) {
|
||||
var correlation = correlations.get(correlationId);
|
||||
if (correlation === undefined) {
|
||||
correlation = new RpcRequestResponse(correlationId);
|
||||
correlations.set(correlationId, correlation);
|
||||
}
|
||||
correlation.sentMessage = msg;
|
||||
correlation.sendReceiptEnvelope = me;
|
||||
correlation.sendReceipt = sr;
|
||||
listener(correlation);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
class HermesClientImpl {
|
||||
constructor(rootUrl, contentTypeHandler) {
|
||||
this.correlationIdCounter = 0;
|
||||
this.correlations = new Map();
|
||||
this.activeSubscriptions = new Map();
|
||||
this.sentMessagesWaitingForAck = new Map();
|
||||
const thisHermesClientImpl = this;
|
||||
this.rootUrl = rootUrl;
|
||||
this.contentTypeHandler = contentTypeHandler;
|
||||
this.mailboxResponseP = createMailbox([Constants.rpcInboxChannelName, Constants.rpcSentChannelName], rootUrl);
|
||||
var tempMailboxResponseP = this.mailboxResponseP;
|
||||
var tempWsUrl = new URL(rootUrl);
|
||||
tempWsUrl.protocol = tempWsUrl.protocol.replace("http", "ws");
|
||||
tempWsUrl.pathname = contentTypeHandler.webSocketUrlPath;
|
||||
this.wsUrl = tempWsUrl.toString();
|
||||
this.currentConn = this.newHermesConnection();
|
||||
}
|
||||
sendPongResponse(mbox, pingMsg, endPoint) {
|
||||
var _a, _b, _c, _d, _e, _f;
|
||||
const correlationId = (_b = (_a = pingMsg.header) === null || _a === void 0 ? void 0 : _a.rpcHeader) === null || _b === void 0 ? void 0 : _b.correlationId;
|
||||
const sender = (_c = pingMsg === null || pingMsg === void 0 ? void 0 : pingMsg.header) === null || _c === void 0 ? void 0 : _c.sender;
|
||||
const contentType = (_e = (_d = pingMsg === null || pingMsg === void 0 ? void 0 : pingMsg.header) === null || _d === void 0 ? void 0 : _d.contentType) !== null && _e !== void 0 ? _e : wsmessages_1.ContentType.UnspecifiedCT;
|
||||
if (correlationId !== undefined && sender !== undefined) {
|
||||
var ping = {};
|
||||
if (pingMsg.data !== undefined) {
|
||||
if (contentType == wsmessages_1.ContentType.Json) {
|
||||
ping = wsmessages_1.Ping.fromJSON(pingMsg.data);
|
||||
}
|
||||
else {
|
||||
ping = wsmessages_1.Ping.decode(pingMsg.data);
|
||||
}
|
||||
}
|
||||
const pong = { payload: ping.payload };
|
||||
var data;
|
||||
if (contentType == wsmessages_1.ContentType.Json) {
|
||||
data = new TextEncoder().encode(JSON.stringify(wsmessages_1.Pong.toJSON(pong)));
|
||||
}
|
||||
else {
|
||||
data = wsmessages_1.Pong.encode(pong).finish();
|
||||
}
|
||||
const idempotentId = mbox.address + correlationId;
|
||||
const smr = {
|
||||
channel: Constants.rpcInboxChannelName,
|
||||
to: [sender],
|
||||
idempotentId: idempotentId,
|
||||
message: {
|
||||
header: {
|
||||
rpcHeader: {
|
||||
correlationId: correlationId,
|
||||
endPoint: endPoint,
|
||||
frameType: wsmessages_1.RpcFrameType.SuccessResponse,
|
||||
errorInfo: undefined,
|
||||
},
|
||||
sender: mbox.address,
|
||||
contentType: (_f = pingMsg === null || pingMsg === void 0 ? void 0 : pingMsg.header) === null || _f === void 0 ? void 0 : _f.contentType,
|
||||
},
|
||||
serverEnvelope: undefined,
|
||||
senderEnvelope: {
|
||||
created: Date.now(),
|
||||
},
|
||||
data: data,
|
||||
},
|
||||
};
|
||||
this.withConn((conn) => {
|
||||
conn.sendSendMessageRequest(smr, true);
|
||||
});
|
||||
}
|
||||
else {
|
||||
console.log("ignoring ping no correlation id", pingMsg);
|
||||
}
|
||||
}
|
||||
reconnect() {
|
||||
this.currentConn = this.newHermesConnection();
|
||||
}
|
||||
newHermesConnection() {
|
||||
const outerThis = this;
|
||||
return new Promise((resolve, reject) => {
|
||||
this.mailboxResponseP.then((mbox) => {
|
||||
var webSocket = new WebSocket(this.wsUrl);
|
||||
webSocket.binaryType = "arraybuffer";
|
||||
webSocket.onopen = function (event) {
|
||||
console.log("hermes client websocket opened, sending first message");
|
||||
const resubscriptions = Object.values(outerThis.activeSubscriptions).map((as) => { return as.protoSubscription; });
|
||||
// send first message
|
||||
const firstMessage = {
|
||||
senderInfo: {
|
||||
readerKey: mbox.readerKey,
|
||||
address: mbox.address,
|
||||
},
|
||||
subscriptions: resubscriptions,
|
||||
mailboxTimeoutInMs: 2 * 60 * 1000, // 2 minutes
|
||||
};
|
||||
const mfc = {
|
||||
firstMessage: firstMessage,
|
||||
};
|
||||
console.log("sending first message");
|
||||
outerThis.contentTypeHandler.sendMessageFromClient(mfc, webSocket);
|
||||
console.log("resolving promise");
|
||||
resolve(new HermesConnection(outerThis, mbox, webSocket));
|
||||
};
|
||||
});
|
||||
});
|
||||
}
|
||||
mailbox() {
|
||||
return this.mailboxResponseP;
|
||||
}
|
||||
async withConn(fn) {
|
||||
return this.currentConn.then((conn) => fn(conn));
|
||||
}
|
||||
async withConnP(fn) {
|
||||
return this.currentConn.then((conn) => fn(conn));
|
||||
}
|
||||
rawRpcCall(request) {
|
||||
return this.withConnP((conn) => {
|
||||
return conn.rawRpcCall(request);
|
||||
});
|
||||
}
|
||||
cdcSubscribe(cdcs, listener) {
|
||||
this.withConn((conn) => {
|
||||
conn.cdcSubscribe(cdcs, listener);
|
||||
});
|
||||
}
|
||||
rpcObserverSubscribe(readerKey, listener) {
|
||||
console.log("outer rpcObserverSubscribe", readerKey);
|
||||
this.withConn((conn) => {
|
||||
console.log("inner rpcObserverSubscribe", readerKey);
|
||||
conn.rpcObserverSubscribe(readerKey, listener);
|
||||
});
|
||||
}
|
||||
channelMessageSubscribe(ms, listener) {
|
||||
this.withConn((conn) => {
|
||||
conn.channelMessageSubscribe(ms, listener);
|
||||
});
|
||||
}
|
||||
channelSendReceiptSubscribe(ms, listener) {
|
||||
this.withConn((conn) => {
|
||||
conn.channelSendReceiptSubscribe(ms, listener);
|
||||
});
|
||||
}
|
||||
sendPing() {
|
||||
this.withConn((conn) => {
|
||||
conn.sendPing();
|
||||
});
|
||||
}
|
||||
}
|
||||
class RpcRequestResponse {
|
||||
constructor(correlationId) {
|
||||
this.correlationId = correlationId;
|
||||
}
|
||||
role() {
|
||||
const ic = this.isClient();
|
||||
if (ic) {
|
||||
return "client";
|
||||
}
|
||||
else if (ic === false) {
|
||||
return "server";
|
||||
}
|
||||
}
|
||||
contentType() {
|
||||
var _a, _b, _c, _d, _e, _f;
|
||||
const contentType = (_f = (_c = (_b = (_a = this.requestMessage()) === null || _a === void 0 ? void 0 : _a.header) === null || _b === void 0 ? void 0 : _b.contentType) !== null && _c !== void 0 ? _c : (_e = (_d = this.responseMessage()) === null || _d === void 0 ? void 0 : _d.header) === null || _e === void 0 ? void 0 : _e.contentType) !== null && _f !== void 0 ? _f : wsmessages_1.ContentType.UnspecifiedCT;
|
||||
return contentType;
|
||||
}
|
||||
isProtobuf() {
|
||||
return this.contentType() === wsmessages_1.ContentType.Protobuf;
|
||||
}
|
||||
isJson() {
|
||||
return this.contentType() === wsmessages_1.ContentType.Json;
|
||||
}
|
||||
isClient() {
|
||||
var _a, _b, _c, _d, _e, _f;
|
||||
const inboxFrameType = (_c = (_b = (_a = this.inboxMessage) === null || _a === void 0 ? void 0 : _a.header) === null || _b === void 0 ? void 0 : _b.rpcHeader) === null || _c === void 0 ? void 0 : _c.frameType;
|
||||
const sentFrameType = (_f = (_e = (_d = this.sentMessage) === null || _d === void 0 ? void 0 : _d.header) === null || _e === void 0 ? void 0 : _e.rpcHeader) === null || _f === void 0 ? void 0 : _f.frameType;
|
||||
if (sentFrameType === wsmessages_1.RpcFrameType.Request) {
|
||||
return true;
|
||||
}
|
||||
else if (inboxFrameType === wsmessages_1.RpcFrameType.Request) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
hasRequestAndResponse() {
|
||||
return this.sendReceiptEnvelope && this.inboxEnvelope ? true : false;
|
||||
}
|
||||
timeStarted() {
|
||||
var _a, _b, _c, _d;
|
||||
const ic = this.isClient();
|
||||
var time = (0, Utils_1.undef)();
|
||||
if (ic === true) {
|
||||
time = (_b = (_a = this.sendReceiptEnvelope) === null || _a === void 0 ? void 0 : _a.serverEnvelope) === null || _b === void 0 ? void 0 : _b.created;
|
||||
}
|
||||
else if (ic === false) {
|
||||
time = (_d = (_c = this.inboxEnvelope) === null || _c === void 0 ? void 0 : _c.serverEnvelope) === null || _d === void 0 ? void 0 : _d.created;
|
||||
}
|
||||
if (time) {
|
||||
return new Date(time);
|
||||
}
|
||||
}
|
||||
timeStartedL() {
|
||||
var _a, _b, _c, _d;
|
||||
const ic = this.isClient();
|
||||
var time = (0, Utils_1.undef)();
|
||||
if (ic === true) {
|
||||
time = (_b = (_a = this.sendReceiptEnvelope) === null || _a === void 0 ? void 0 : _a.serverEnvelope) === null || _b === void 0 ? void 0 : _b.created;
|
||||
}
|
||||
else if (ic === false) {
|
||||
time = (_d = (_c = this.inboxEnvelope) === null || _c === void 0 ? void 0 : _c.serverEnvelope) === null || _d === void 0 ? void 0 : _d.created;
|
||||
}
|
||||
return time;
|
||||
}
|
||||
timeCompleted() {
|
||||
var _a, _b, _c, _d;
|
||||
const ic = this.isClient();
|
||||
var time = undefined;
|
||||
if (ic === false) {
|
||||
time = (_b = (_a = this.sendReceiptEnvelope) === null || _a === void 0 ? void 0 : _a.serverEnvelope) === null || _b === void 0 ? void 0 : _b.created;
|
||||
}
|
||||
else if (ic === true) {
|
||||
time = (_d = (_c = this.inboxEnvelope) === null || _c === void 0 ? void 0 : _c.serverEnvelope) === null || _d === void 0 ? void 0 : _d.created;
|
||||
}
|
||||
if (time) {
|
||||
return new Date(time);
|
||||
}
|
||||
}
|
||||
durationInMillis() {
|
||||
var _a, _b;
|
||||
const ts = (_a = this.timeStarted()) === null || _a === void 0 ? void 0 : _a.getTime();
|
||||
const tc = (_b = this.timeCompleted()) === null || _b === void 0 ? void 0 : _b.getTime();
|
||||
if (ts && tc) {
|
||||
return tc - ts;
|
||||
}
|
||||
}
|
||||
endPoint() {
|
||||
var _a, _b, _c;
|
||||
return (_c = (_b = (_a = this.requestMessage()) === null || _a === void 0 ? void 0 : _a.header) === null || _b === void 0 ? void 0 : _b.rpcHeader) === null || _c === void 0 ? void 0 : _c.endPoint;
|
||||
}
|
||||
requestMessage() {
|
||||
const ic = this.isClient();
|
||||
if (ic === true) {
|
||||
return this.sentMessage;
|
||||
}
|
||||
else if (ic === false) {
|
||||
return this.inboxMessage;
|
||||
}
|
||||
}
|
||||
requestEnvelope() {
|
||||
const ic = this.isClient();
|
||||
if (ic === true) {
|
||||
return this.sendReceiptEnvelope;
|
||||
}
|
||||
else if (ic === false) {
|
||||
return this.inboxEnvelope;
|
||||
}
|
||||
}
|
||||
responseMessage() {
|
||||
const ic = this.isClient();
|
||||
if (ic === true) {
|
||||
return this.inboxMessage;
|
||||
}
|
||||
else if (ic === false) {
|
||||
return this.sentMessage;
|
||||
}
|
||||
}
|
||||
responseEnvelope() {
|
||||
const ic = this.isClient();
|
||||
if (ic === true) {
|
||||
return this.inboxEnvelope;
|
||||
}
|
||||
else if (ic === false) {
|
||||
return this.sendReceiptEnvelope;
|
||||
}
|
||||
}
|
||||
status() {
|
||||
var _a, _b, _c;
|
||||
const frameType = (_c = (_b = (_a = this.responseMessage()) === null || _a === void 0 ? void 0 : _a.header) === null || _b === void 0 ? void 0 : _b.rpcHeader) === null || _c === void 0 ? void 0 : _c.frameType;
|
||||
if (!frameType) {
|
||||
return "";
|
||||
}
|
||||
else if (frameType === wsmessages_1.RpcFrameType.ErrorResponse) {
|
||||
return "error";
|
||||
}
|
||||
else if (frameType === wsmessages_1.RpcFrameType.SuccessResponse) {
|
||||
return "success";
|
||||
}
|
||||
else {
|
||||
return `Unexpected frame types ${frameType}`;
|
||||
}
|
||||
}
|
||||
async processSchema(reqOrResp, data) {
|
||||
if (this.isJson()) {
|
||||
const jsonStr = new TextDecoder().decode(data);
|
||||
return JSON.parse(jsonStr);
|
||||
}
|
||||
else {
|
||||
const endPoint = this.endPoint();
|
||||
if (endPoint === undefined) {
|
||||
return {
|
||||
"error": "no endpoint"
|
||||
};
|
||||
}
|
||||
if (data === undefined) {
|
||||
return {};
|
||||
}
|
||||
return protobufToJson(endPoint, reqOrResp, data);
|
||||
}
|
||||
}
|
||||
async responseObj() {
|
||||
var _a;
|
||||
return this.processSchema("response", (_a = this.responseMessage()) === null || _a === void 0 ? void 0 : _a.data);
|
||||
}
|
||||
async requestObj() {
|
||||
var _a;
|
||||
return this.processSchema("request", (_a = this.requestMessage()) === null || _a === void 0 ? void 0 : _a.data);
|
||||
}
|
||||
}
|
||||
exports.RpcRequestResponse = RpcRequestResponse;
|
||||
const GlobalClient = {
|
||||
get: (0, Utils_1.memoize)(() => newHermesClient("https://hermes-go.ahsrcm.com", JsonContentTypeHandler))
|
||||
};
|
||||
exports.default = GlobalClient;
|
||||
function runHermesClientTest() {
|
||||
}
|
||||
exports.runHermesClientTest = runHermesClientTest;
|
||||
function runHermesClientTest2() {
|
||||
// const hc = newHermesClient("https://hermes-go.ahsrcm.com", ContentType.Protobuf);
|
||||
const hc = newHermesClient("https://hermes-go.ahsrcm.com", JsonContentTypeHandler);
|
||||
hc.mailbox().then((mbox) => {
|
||||
const cdcs = {
|
||||
tables: [
|
||||
{
|
||||
database: "nefario",
|
||||
table: "service",
|
||||
},
|
||||
],
|
||||
startSeq: "new",
|
||||
};
|
||||
hc.cdcSubscribe(cdcs, (cdcEvent, a) => {
|
||||
console.log("cdcEvent", cdcEvent);
|
||||
});
|
||||
});
|
||||
// hc.correlatedRpcReader("rrb07167144dc644a0be22a85301afea7e" , (correlation) => {
|
||||
// console.log("correlation", correlation);
|
||||
// });
|
||||
}
|
||||
exports.runHermesClientTest2 = runHermesClientTest2;
|
||||
async function protobufToJson(schemaName, frametype, bytes) {
|
||||
// const mboxObj = CreateMailboxRequest.toJSON(mbox);
|
||||
// const mboxJson = JSON.stringify(mboxObj);
|
||||
// let mailboxResponse: CreateMailboxResponse | undefined = undefined;
|
||||
const rootUrl = GlobalClient.get().rootUrl;
|
||||
const response = await fetch(`${rootUrl}/api/proto_to_json?schema=${schemaName}&frametype=${frametype}`, {
|
||||
method: "POST",
|
||||
body: bytes,
|
||||
});
|
||||
if (response.ok) {
|
||||
const jsonStr = await response.text();
|
||||
return JSON.parse(jsonStr);
|
||||
}
|
||||
else {
|
||||
throw new Error(`proto_to_json failed with status ${response.status}`);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,201 @@
|
|||
import * as _m0 from "protobufjs/minimal";
|
||||
export declare const protobufPackage = "google.protobuf";
|
||||
/**
|
||||
* `NullValue` is a singleton enumeration to represent the null value for the
|
||||
* `Value` type union.
|
||||
*
|
||||
* The JSON representation for `NullValue` is JSON `null`.
|
||||
*/
|
||||
export declare enum NullValue {
|
||||
/** NULL_VALUE - Null value. */
|
||||
NULL_VALUE = 0,
|
||||
UNRECOGNIZED = -1
|
||||
}
|
||||
export declare function nullValueFromJSON(object: any): NullValue;
|
||||
export declare function nullValueToJSON(object: NullValue): string;
|
||||
/**
|
||||
* `Struct` represents a structured data value, consisting of fields
|
||||
* which map to dynamically typed values. In some languages, `Struct`
|
||||
* might be supported by a native representation. For example, in
|
||||
* scripting languages like JS a struct is represented as an
|
||||
* object. The details of that representation are described together
|
||||
* with the proto support for the language.
|
||||
*
|
||||
* The JSON representation for `Struct` is JSON object.
|
||||
*/
|
||||
export interface Struct {
|
||||
/** Unordered map of dynamically typed values. */
|
||||
fields: {
|
||||
[key: string]: any | undefined;
|
||||
};
|
||||
}
|
||||
export interface Struct_FieldsEntry {
|
||||
key: string;
|
||||
value: any | undefined;
|
||||
}
|
||||
/**
|
||||
* `Value` represents a dynamically typed value which can be either
|
||||
* null, a number, a string, a boolean, a recursive struct value, or a
|
||||
* list of values. A producer of value is expected to set one of these
|
||||
* variants. Absence of any variant indicates an error.
|
||||
*
|
||||
* The JSON representation for `Value` is JSON value.
|
||||
*/
|
||||
export interface Value {
|
||||
/** Represents a null value. */
|
||||
nullValue?: NullValue | undefined;
|
||||
/** Represents a double value. */
|
||||
numberValue?: number | undefined;
|
||||
/** Represents a string value. */
|
||||
stringValue?: string | undefined;
|
||||
/** Represents a boolean value. */
|
||||
boolValue?: boolean | undefined;
|
||||
/** Represents a structured value. */
|
||||
structValue?: {
|
||||
[key: string]: any;
|
||||
} | undefined;
|
||||
/** Represents a repeated `Value`. */
|
||||
listValue?: Array<any> | undefined;
|
||||
}
|
||||
/**
|
||||
* `ListValue` is a wrapper around a repeated field of values.
|
||||
*
|
||||
* The JSON representation for `ListValue` is JSON array.
|
||||
*/
|
||||
export interface ListValue {
|
||||
/** Repeated field of dynamically typed values. */
|
||||
values: any[];
|
||||
}
|
||||
export declare const Struct: {
|
||||
encode(message: Struct, writer?: _m0.Writer): _m0.Writer;
|
||||
decode(input: _m0.Reader | Uint8Array, length?: number): Struct;
|
||||
fromJSON(object: any): Struct;
|
||||
toJSON(message: Struct): unknown;
|
||||
create<I extends {
|
||||
fields?: {
|
||||
[x: string]: any;
|
||||
} | undefined;
|
||||
} & {
|
||||
fields?: ({
|
||||
[x: string]: any;
|
||||
} & {
|
||||
[x: string]: any;
|
||||
} & { [K in Exclude<keyof I["fields"], string | number>]: never; }) | undefined;
|
||||
} & { [K_1 in Exclude<keyof I, "fields">]: never; }>(base?: I): Struct;
|
||||
fromPartial<I_1 extends {
|
||||
fields?: {
|
||||
[x: string]: any;
|
||||
} | undefined;
|
||||
} & {
|
||||
fields?: ({
|
||||
[x: string]: any;
|
||||
} & {
|
||||
[x: string]: any;
|
||||
} & { [K_2 in Exclude<keyof I_1["fields"], string | number>]: never; }) | undefined;
|
||||
} & { [K_3 in Exclude<keyof I_1, "fields">]: never; }>(object: I_1): Struct;
|
||||
wrap(object: {
|
||||
[key: string]: any;
|
||||
} | undefined): Struct;
|
||||
unwrap(message: Struct): {
|
||||
[key: string]: any;
|
||||
};
|
||||
};
|
||||
export declare const Struct_FieldsEntry: {
|
||||
encode(message: Struct_FieldsEntry, writer?: _m0.Writer): _m0.Writer;
|
||||
decode(input: _m0.Reader | Uint8Array, length?: number): Struct_FieldsEntry;
|
||||
fromJSON(object: any): Struct_FieldsEntry;
|
||||
toJSON(message: Struct_FieldsEntry): unknown;
|
||||
create<I extends {
|
||||
key?: string | undefined;
|
||||
value?: any | undefined;
|
||||
} & {
|
||||
key?: string | undefined;
|
||||
value?: any | undefined;
|
||||
} & { [K in Exclude<keyof I, keyof Struct_FieldsEntry>]: never; }>(base?: I): Struct_FieldsEntry;
|
||||
fromPartial<I_1 extends {
|
||||
key?: string | undefined;
|
||||
value?: any | undefined;
|
||||
} & {
|
||||
key?: string | undefined;
|
||||
value?: any | undefined;
|
||||
} & { [K_1 in Exclude<keyof I_1, keyof Struct_FieldsEntry>]: never; }>(object: I_1): Struct_FieldsEntry;
|
||||
};
|
||||
export declare const Value: {
|
||||
encode(message: Value, writer?: _m0.Writer): _m0.Writer;
|
||||
decode(input: _m0.Reader | Uint8Array, length?: number): Value;
|
||||
fromJSON(object: any): Value;
|
||||
toJSON(message: Value): unknown;
|
||||
create<I extends {
|
||||
nullValue?: NullValue | undefined;
|
||||
numberValue?: number | undefined;
|
||||
stringValue?: string | undefined;
|
||||
boolValue?: boolean | undefined;
|
||||
structValue?: {
|
||||
[x: string]: any;
|
||||
} | undefined;
|
||||
listValue?: any[] | undefined;
|
||||
} & {
|
||||
nullValue?: NullValue | undefined;
|
||||
numberValue?: number | undefined;
|
||||
stringValue?: string | undefined;
|
||||
boolValue?: boolean | undefined;
|
||||
structValue?: ({
|
||||
[x: string]: any;
|
||||
} & {
|
||||
[x: string]: any;
|
||||
} & { [K in Exclude<keyof I["structValue"], string | number>]: never; }) | undefined;
|
||||
listValue?: (any[] & any[] & { [K_1 in Exclude<keyof I["listValue"], keyof any[]>]: never; }) | undefined;
|
||||
} & { [K_2 in Exclude<keyof I, keyof Value>]: never; }>(base?: I): Value;
|
||||
fromPartial<I_1 extends {
|
||||
nullValue?: NullValue | undefined;
|
||||
numberValue?: number | undefined;
|
||||
stringValue?: string | undefined;
|
||||
boolValue?: boolean | undefined;
|
||||
structValue?: {
|
||||
[x: string]: any;
|
||||
} | undefined;
|
||||
listValue?: any[] | undefined;
|
||||
} & {
|
||||
nullValue?: NullValue | undefined;
|
||||
numberValue?: number | undefined;
|
||||
stringValue?: string | undefined;
|
||||
boolValue?: boolean | undefined;
|
||||
structValue?: ({
|
||||
[x: string]: any;
|
||||
} & {
|
||||
[x: string]: any;
|
||||
} & { [K_3 in Exclude<keyof I_1["structValue"], string | number>]: never; }) | undefined;
|
||||
listValue?: (any[] & any[] & { [K_4 in Exclude<keyof I_1["listValue"], keyof any[]>]: never; }) | undefined;
|
||||
} & { [K_5 in Exclude<keyof I_1, keyof Value>]: never; }>(object: I_1): Value;
|
||||
wrap(value: any): Value;
|
||||
unwrap(message: any): string | number | boolean | Object | null | Array<any> | undefined;
|
||||
};
|
||||
export declare const ListValue: {
|
||||
encode(message: ListValue, writer?: _m0.Writer): _m0.Writer;
|
||||
decode(input: _m0.Reader | Uint8Array, length?: number): ListValue;
|
||||
fromJSON(object: any): ListValue;
|
||||
toJSON(message: ListValue): unknown;
|
||||
create<I extends {
|
||||
values?: any[] | undefined;
|
||||
} & {
|
||||
values?: (any[] & any[] & { [K in Exclude<keyof I["values"], keyof any[]>]: never; }) | undefined;
|
||||
} & { [K_1 in Exclude<keyof I, "values">]: never; }>(base?: I): ListValue;
|
||||
fromPartial<I_1 extends {
|
||||
values?: any[] | undefined;
|
||||
} & {
|
||||
values?: (any[] & any[] & { [K_2 in Exclude<keyof I_1["values"], keyof any[]>]: never; }) | undefined;
|
||||
} & { [K_3 in Exclude<keyof I_1, "values">]: never; }>(object: I_1): ListValue;
|
||||
wrap(array: Array<any> | undefined): ListValue;
|
||||
unwrap(message: ListValue): Array<any>;
|
||||
};
|
||||
type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined;
|
||||
export type DeepPartial<T> = T extends Builtin ? T : T extends globalThis.Array<infer U> ? globalThis.Array<DeepPartial<U>> : T extends ReadonlyArray<infer U> ? ReadonlyArray<DeepPartial<U>> : T extends {} ? {
|
||||
[K in keyof T]?: DeepPartial<T[K]>;
|
||||
} : Partial<T>;
|
||||
type KeysOfUnion<T> = T extends T ? keyof T : never;
|
||||
export type Exact<P, I extends P> = P extends Builtin ? P : P & {
|
||||
[K in keyof P]: Exact<P[K], I[K]>;
|
||||
} & {
|
||||
[K in Exclude<keyof I, KeysOfUnion<P>>]: never;
|
||||
};
|
||||
export {};
|
||||
|
|
@ -0,0 +1,469 @@
|
|||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.ListValue = exports.Value = exports.Struct_FieldsEntry = exports.Struct = exports.nullValueToJSON = exports.nullValueFromJSON = exports.NullValue = exports.protobufPackage = void 0;
|
||||
/* eslint-disable */
|
||||
const _m0 = __importStar(require("protobufjs/minimal"));
|
||||
exports.protobufPackage = "google.protobuf";
|
||||
/**
|
||||
* `NullValue` is a singleton enumeration to represent the null value for the
|
||||
* `Value` type union.
|
||||
*
|
||||
* The JSON representation for `NullValue` is JSON `null`.
|
||||
*/
|
||||
var NullValue;
|
||||
(function (NullValue) {
|
||||
/** NULL_VALUE - Null value. */
|
||||
NullValue[NullValue["NULL_VALUE"] = 0] = "NULL_VALUE";
|
||||
NullValue[NullValue["UNRECOGNIZED"] = -1] = "UNRECOGNIZED";
|
||||
})(NullValue || (exports.NullValue = NullValue = {}));
|
||||
function nullValueFromJSON(object) {
|
||||
switch (object) {
|
||||
case 0:
|
||||
case "NULL_VALUE":
|
||||
return NullValue.NULL_VALUE;
|
||||
case -1:
|
||||
case "UNRECOGNIZED":
|
||||
default:
|
||||
return NullValue.UNRECOGNIZED;
|
||||
}
|
||||
}
|
||||
exports.nullValueFromJSON = nullValueFromJSON;
|
||||
function nullValueToJSON(object) {
|
||||
switch (object) {
|
||||
case NullValue.NULL_VALUE:
|
||||
return "NULL_VALUE";
|
||||
case NullValue.UNRECOGNIZED:
|
||||
default:
|
||||
return "UNRECOGNIZED";
|
||||
}
|
||||
}
|
||||
exports.nullValueToJSON = nullValueToJSON;
|
||||
function createBaseStruct() {
|
||||
return { fields: {} };
|
||||
}
|
||||
exports.Struct = {
|
||||
encode(message, writer = _m0.Writer.create()) {
|
||||
Object.entries(message.fields).forEach(([key, value]) => {
|
||||
if (value !== undefined) {
|
||||
exports.Struct_FieldsEntry.encode({ key: key, value }, writer.uint32(10).fork()).ldelim();
|
||||
}
|
||||
});
|
||||
return writer;
|
||||
},
|
||||
decode(input, length) {
|
||||
const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseStruct();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
switch (tag >>> 3) {
|
||||
case 1:
|
||||
if (tag !== 10) {
|
||||
break;
|
||||
}
|
||||
const entry1 = exports.Struct_FieldsEntry.decode(reader, reader.uint32());
|
||||
if (entry1.value !== undefined) {
|
||||
message.fields[entry1.key] = entry1.value;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if ((tag & 7) === 4 || tag === 0) {
|
||||
break;
|
||||
}
|
||||
reader.skipType(tag & 7);
|
||||
}
|
||||
return message;
|
||||
},
|
||||
fromJSON(object) {
|
||||
return {
|
||||
fields: isObject(object.fields)
|
||||
? Object.entries(object.fields).reduce((acc, [key, value]) => {
|
||||
acc[key] = value;
|
||||
return acc;
|
||||
}, {})
|
||||
: {},
|
||||
};
|
||||
},
|
||||
toJSON(message) {
|
||||
const obj = {};
|
||||
if (message.fields) {
|
||||
const entries = Object.entries(message.fields);
|
||||
if (entries.length > 0) {
|
||||
obj.fields = {};
|
||||
entries.forEach(([k, v]) => {
|
||||
obj.fields[k] = v;
|
||||
});
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
},
|
||||
create(base) {
|
||||
return exports.Struct.fromPartial(base !== null && base !== void 0 ? base : {});
|
||||
},
|
||||
fromPartial(object) {
|
||||
var _a;
|
||||
const message = createBaseStruct();
|
||||
message.fields = Object.entries((_a = object.fields) !== null && _a !== void 0 ? _a : {}).reduce((acc, [key, value]) => {
|
||||
if (value !== undefined) {
|
||||
acc[key] = value;
|
||||
}
|
||||
return acc;
|
||||
}, {});
|
||||
return message;
|
||||
},
|
||||
wrap(object) {
|
||||
const struct = createBaseStruct();
|
||||
if (object !== undefined) {
|
||||
Object.keys(object).forEach((key) => {
|
||||
struct.fields[key] = object[key];
|
||||
});
|
||||
}
|
||||
return struct;
|
||||
},
|
||||
unwrap(message) {
|
||||
const object = {};
|
||||
if (message.fields) {
|
||||
Object.keys(message.fields).forEach((key) => {
|
||||
object[key] = message.fields[key];
|
||||
});
|
||||
}
|
||||
return object;
|
||||
},
|
||||
};
|
||||
function createBaseStruct_FieldsEntry() {
|
||||
return { key: "", value: undefined };
|
||||
}
|
||||
exports.Struct_FieldsEntry = {
|
||||
encode(message, writer = _m0.Writer.create()) {
|
||||
if (message.key !== "") {
|
||||
writer.uint32(10).string(message.key);
|
||||
}
|
||||
if (message.value !== undefined) {
|
||||
exports.Value.encode(exports.Value.wrap(message.value), writer.uint32(18).fork()).ldelim();
|
||||
}
|
||||
return writer;
|
||||
},
|
||||
decode(input, length) {
|
||||
const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseStruct_FieldsEntry();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
switch (tag >>> 3) {
|
||||
case 1:
|
||||
if (tag !== 10) {
|
||||
break;
|
||||
}
|
||||
message.key = reader.string();
|
||||
continue;
|
||||
case 2:
|
||||
if (tag !== 18) {
|
||||
break;
|
||||
}
|
||||
message.value = exports.Value.unwrap(exports.Value.decode(reader, reader.uint32()));
|
||||
continue;
|
||||
}
|
||||
if ((tag & 7) === 4 || tag === 0) {
|
||||
break;
|
||||
}
|
||||
reader.skipType(tag & 7);
|
||||
}
|
||||
return message;
|
||||
},
|
||||
fromJSON(object) {
|
||||
return {
|
||||
key: isSet(object.key) ? globalThis.String(object.key) : "",
|
||||
value: isSet(object === null || object === void 0 ? void 0 : object.value) ? object.value : undefined,
|
||||
};
|
||||
},
|
||||
toJSON(message) {
|
||||
const obj = {};
|
||||
if (message.key !== "") {
|
||||
obj.key = message.key;
|
||||
}
|
||||
if (message.value !== undefined) {
|
||||
obj.value = message.value;
|
||||
}
|
||||
return obj;
|
||||
},
|
||||
create(base) {
|
||||
return exports.Struct_FieldsEntry.fromPartial(base !== null && base !== void 0 ? base : {});
|
||||
},
|
||||
fromPartial(object) {
|
||||
var _a, _b;
|
||||
const message = createBaseStruct_FieldsEntry();
|
||||
message.key = (_a = object.key) !== null && _a !== void 0 ? _a : "";
|
||||
message.value = (_b = object.value) !== null && _b !== void 0 ? _b : undefined;
|
||||
return message;
|
||||
},
|
||||
};
|
||||
function createBaseValue() {
|
||||
return {
|
||||
nullValue: undefined,
|
||||
numberValue: undefined,
|
||||
stringValue: undefined,
|
||||
boolValue: undefined,
|
||||
structValue: undefined,
|
||||
listValue: undefined,
|
||||
};
|
||||
}
|
||||
exports.Value = {
|
||||
encode(message, writer = _m0.Writer.create()) {
|
||||
if (message.nullValue !== undefined) {
|
||||
writer.uint32(8).int32(message.nullValue);
|
||||
}
|
||||
if (message.numberValue !== undefined) {
|
||||
writer.uint32(17).double(message.numberValue);
|
||||
}
|
||||
if (message.stringValue !== undefined) {
|
||||
writer.uint32(26).string(message.stringValue);
|
||||
}
|
||||
if (message.boolValue !== undefined) {
|
||||
writer.uint32(32).bool(message.boolValue);
|
||||
}
|
||||
if (message.structValue !== undefined) {
|
||||
exports.Struct.encode(exports.Struct.wrap(message.structValue), writer.uint32(42).fork()).ldelim();
|
||||
}
|
||||
if (message.listValue !== undefined) {
|
||||
exports.ListValue.encode(exports.ListValue.wrap(message.listValue), writer.uint32(50).fork()).ldelim();
|
||||
}
|
||||
return writer;
|
||||
},
|
||||
decode(input, length) {
|
||||
const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseValue();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
switch (tag >>> 3) {
|
||||
case 1:
|
||||
if (tag !== 8) {
|
||||
break;
|
||||
}
|
||||
message.nullValue = reader.int32();
|
||||
continue;
|
||||
case 2:
|
||||
if (tag !== 17) {
|
||||
break;
|
||||
}
|
||||
message.numberValue = reader.double();
|
||||
continue;
|
||||
case 3:
|
||||
if (tag !== 26) {
|
||||
break;
|
||||
}
|
||||
message.stringValue = reader.string();
|
||||
continue;
|
||||
case 4:
|
||||
if (tag !== 32) {
|
||||
break;
|
||||
}
|
||||
message.boolValue = reader.bool();
|
||||
continue;
|
||||
case 5:
|
||||
if (tag !== 42) {
|
||||
break;
|
||||
}
|
||||
message.structValue = exports.Struct.unwrap(exports.Struct.decode(reader, reader.uint32()));
|
||||
continue;
|
||||
case 6:
|
||||
if (tag !== 50) {
|
||||
break;
|
||||
}
|
||||
message.listValue = exports.ListValue.unwrap(exports.ListValue.decode(reader, reader.uint32()));
|
||||
continue;
|
||||
}
|
||||
if ((tag & 7) === 4 || tag === 0) {
|
||||
break;
|
||||
}
|
||||
reader.skipType(tag & 7);
|
||||
}
|
||||
return message;
|
||||
},
|
||||
fromJSON(object) {
|
||||
return {
|
||||
nullValue: isSet(object.nullValue) ? nullValueFromJSON(object.nullValue) : undefined,
|
||||
numberValue: isSet(object.numberValue) ? globalThis.Number(object.numberValue) : undefined,
|
||||
stringValue: isSet(object.stringValue) ? globalThis.String(object.stringValue) : undefined,
|
||||
boolValue: isSet(object.boolValue) ? globalThis.Boolean(object.boolValue) : undefined,
|
||||
structValue: isObject(object.structValue) ? object.structValue : undefined,
|
||||
listValue: globalThis.Array.isArray(object.listValue) ? [...object.listValue] : undefined,
|
||||
};
|
||||
},
|
||||
toJSON(message) {
|
||||
const obj = {};
|
||||
if (message.nullValue !== undefined) {
|
||||
obj.nullValue = nullValueToJSON(message.nullValue);
|
||||
}
|
||||
if (message.numberValue !== undefined) {
|
||||
obj.numberValue = message.numberValue;
|
||||
}
|
||||
if (message.stringValue !== undefined) {
|
||||
obj.stringValue = message.stringValue;
|
||||
}
|
||||
if (message.boolValue !== undefined) {
|
||||
obj.boolValue = message.boolValue;
|
||||
}
|
||||
if (message.structValue !== undefined) {
|
||||
obj.structValue = message.structValue;
|
||||
}
|
||||
if (message.listValue !== undefined) {
|
||||
obj.listValue = message.listValue;
|
||||
}
|
||||
return obj;
|
||||
},
|
||||
create(base) {
|
||||
return exports.Value.fromPartial(base !== null && base !== void 0 ? base : {});
|
||||
},
|
||||
fromPartial(object) {
|
||||
var _a, _b, _c, _d, _e, _f;
|
||||
const message = createBaseValue();
|
||||
message.nullValue = (_a = object.nullValue) !== null && _a !== void 0 ? _a : undefined;
|
||||
message.numberValue = (_b = object.numberValue) !== null && _b !== void 0 ? _b : undefined;
|
||||
message.stringValue = (_c = object.stringValue) !== null && _c !== void 0 ? _c : undefined;
|
||||
message.boolValue = (_d = object.boolValue) !== null && _d !== void 0 ? _d : undefined;
|
||||
message.structValue = (_e = object.structValue) !== null && _e !== void 0 ? _e : undefined;
|
||||
message.listValue = (_f = object.listValue) !== null && _f !== void 0 ? _f : undefined;
|
||||
return message;
|
||||
},
|
||||
wrap(value) {
|
||||
const result = createBaseValue();
|
||||
if (value === null) {
|
||||
result.nullValue = NullValue.NULL_VALUE;
|
||||
}
|
||||
else if (typeof value === "boolean") {
|
||||
result.boolValue = value;
|
||||
}
|
||||
else if (typeof value === "number") {
|
||||
result.numberValue = value;
|
||||
}
|
||||
else if (typeof value === "string") {
|
||||
result.stringValue = value;
|
||||
}
|
||||
else if (globalThis.Array.isArray(value)) {
|
||||
result.listValue = value;
|
||||
}
|
||||
else if (typeof value === "object") {
|
||||
result.structValue = value;
|
||||
}
|
||||
else if (typeof value !== "undefined") {
|
||||
throw new globalThis.Error("Unsupported any value type: " + typeof value);
|
||||
}
|
||||
return result;
|
||||
},
|
||||
unwrap(message) {
|
||||
if (message.stringValue !== undefined) {
|
||||
return message.stringValue;
|
||||
}
|
||||
else if ((message === null || message === void 0 ? void 0 : message.numberValue) !== undefined) {
|
||||
return message.numberValue;
|
||||
}
|
||||
else if ((message === null || message === void 0 ? void 0 : message.boolValue) !== undefined) {
|
||||
return message.boolValue;
|
||||
}
|
||||
else if ((message === null || message === void 0 ? void 0 : message.structValue) !== undefined) {
|
||||
return message.structValue;
|
||||
}
|
||||
else if ((message === null || message === void 0 ? void 0 : message.listValue) !== undefined) {
|
||||
return message.listValue;
|
||||
}
|
||||
else if ((message === null || message === void 0 ? void 0 : message.nullValue) !== undefined) {
|
||||
return null;
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
};
|
||||
function createBaseListValue() {
|
||||
return { values: [] };
|
||||
}
|
||||
exports.ListValue = {
|
||||
encode(message, writer = _m0.Writer.create()) {
|
||||
for (const v of message.values) {
|
||||
exports.Value.encode(exports.Value.wrap(v), writer.uint32(10).fork()).ldelim();
|
||||
}
|
||||
return writer;
|
||||
},
|
||||
decode(input, length) {
|
||||
const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseListValue();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
switch (tag >>> 3) {
|
||||
case 1:
|
||||
if (tag !== 10) {
|
||||
break;
|
||||
}
|
||||
message.values.push(exports.Value.unwrap(exports.Value.decode(reader, reader.uint32())));
|
||||
continue;
|
||||
}
|
||||
if ((tag & 7) === 4 || tag === 0) {
|
||||
break;
|
||||
}
|
||||
reader.skipType(tag & 7);
|
||||
}
|
||||
return message;
|
||||
},
|
||||
fromJSON(object) {
|
||||
return { values: globalThis.Array.isArray(object === null || object === void 0 ? void 0 : object.values) ? [...object.values] : [] };
|
||||
},
|
||||
toJSON(message) {
|
||||
var _a;
|
||||
const obj = {};
|
||||
if ((_a = message.values) === null || _a === void 0 ? void 0 : _a.length) {
|
||||
obj.values = message.values;
|
||||
}
|
||||
return obj;
|
||||
},
|
||||
create(base) {
|
||||
return exports.ListValue.fromPartial(base !== null && base !== void 0 ? base : {});
|
||||
},
|
||||
fromPartial(object) {
|
||||
var _a;
|
||||
const message = createBaseListValue();
|
||||
message.values = ((_a = object.values) === null || _a === void 0 ? void 0 : _a.map((e) => e)) || [];
|
||||
return message;
|
||||
},
|
||||
wrap(array) {
|
||||
const result = createBaseListValue();
|
||||
result.values = array !== null && array !== void 0 ? array : [];
|
||||
return result;
|
||||
},
|
||||
unwrap(message) {
|
||||
if ((message === null || message === void 0 ? void 0 : message.hasOwnProperty("values")) && globalThis.Array.isArray(message.values)) {
|
||||
return message.values;
|
||||
}
|
||||
else {
|
||||
return message;
|
||||
}
|
||||
},
|
||||
};
|
||||
function isObject(value) {
|
||||
return typeof value === "object" && value !== null;
|
||||
}
|
||||
function isSet(value) {
|
||||
return value !== null && value !== undefined;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,2 @@
|
|||
export declare function undef<A>(): A | undefined;
|
||||
export declare function memoize<A>(fn: () => A): () => A;
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
export function undef() {
|
||||
return undefined;
|
||||
}
|
||||
export function memoize(fn) {
|
||||
let memo;
|
||||
return () => {
|
||||
if (memo === undefined) {
|
||||
memo = fn();
|
||||
}
|
||||
return memo;
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
import { ContentType, Message, MessageFromClient, CreateMailboxResponse, KeyValPair, MessageEnvelope, SendReceipt } from "./proto/wsmessages";
|
||||
export interface ContentTypeHandler {
|
||||
readonly webSocketUrlPath: string;
|
||||
sendMessageFromClient(mfc: MessageFromClient, ws: WebSocket): void;
|
||||
}
|
||||
export declare const ContentTypeHandler: {
|
||||
Json: ContentTypeHandler;
|
||||
Protobuf: ContentTypeHandler;
|
||||
};
|
||||
export declare function newHermesClient(rootUrl: string, contentTypeHandler: ContentTypeHandler): HermesClient;
|
||||
export interface ChangeDataCaptureEvent {
|
||||
id: string;
|
||||
schema: string;
|
||||
table: string;
|
||||
action: string;
|
||||
data: any;
|
||||
commitTime: string;
|
||||
}
|
||||
interface RawRpcRequest {
|
||||
to: string;
|
||||
endPoint: string;
|
||||
body?: Uint8Array;
|
||||
contentType?: ContentType;
|
||||
headers?: KeyValPair[];
|
||||
state?: Uint8Array;
|
||||
}
|
||||
export declare class RpcRequestResponse {
|
||||
correlationId: string;
|
||||
sendReceiptEnvelope: MessageEnvelope | undefined;
|
||||
sendReceipt: SendReceipt | undefined;
|
||||
sentMessage: Message | undefined;
|
||||
inboxEnvelope: MessageEnvelope | undefined;
|
||||
inboxMessage: Message | undefined;
|
||||
constructor(correlationId: string);
|
||||
role(): string | undefined;
|
||||
contentType(): ContentType;
|
||||
isProtobuf(): boolean;
|
||||
isJson(): boolean;
|
||||
isClient(): boolean | undefined;
|
||||
hasRequestAndResponse(): boolean;
|
||||
timeStarted(): Date | undefined;
|
||||
timeStartedL(): number | undefined;
|
||||
timeCompleted(): Date | undefined;
|
||||
durationInMillis(): number | undefined;
|
||||
endPoint(): string | undefined;
|
||||
requestMessage(): Message | undefined;
|
||||
requestEnvelope(): MessageEnvelope | undefined;
|
||||
responseMessage(): Message | undefined;
|
||||
responseEnvelope(): MessageEnvelope | undefined;
|
||||
status(): string;
|
||||
processSchema(reqOrResp: "request" | "response", data?: Uint8Array): Promise<any>;
|
||||
responseObj(): Promise<any>;
|
||||
requestObj(): Promise<any>;
|
||||
}
|
||||
declare const GlobalClient: {
|
||||
get: () => HermesClient;
|
||||
};
|
||||
export default GlobalClient;
|
||||
export declare function runHermesClientTest(): void;
|
||||
export declare function runHermesClientTest2(): void;
|
||||
export interface CdcSubscription {
|
||||
tables: CdcTable[];
|
||||
startSeq?: string;
|
||||
}
|
||||
export interface CdcTable {
|
||||
database: string;
|
||||
table: string;
|
||||
}
|
||||
export interface HermesClient {
|
||||
readonly rootUrl: string;
|
||||
mailbox(): Promise<CreateMailboxResponse>;
|
||||
rawRpcCall(request: RawRpcRequest): Promise<Message>;
|
||||
cdcSubscribe<A>(cdcs: CdcSubscription, listener: (cdcEvent: ChangeDataCaptureEvent, a: A) => void): void;
|
||||
rpcObserverSubscribe(readerKey: string, listener: (correlation: RpcRequestResponse) => void): void;
|
||||
}
|
||||
|
|
@ -0,0 +1,682 @@
|
|||
import { ContentType, Message, MessageFromClient, MessageToClient, CreateMailboxResponse, CreateMailboxRequest, RpcFrameType, SendReceipt, Ping, Pong, } from "./proto/wsmessages";
|
||||
import { memoize, undef } from "../Utils";
|
||||
const JsonContentTypeHandler = {
|
||||
webSocketUrlPath: "/api/ws/send_receive_json",
|
||||
sendMessageFromClient(mfc, ws) {
|
||||
const obj = MessageFromClient.toJSON(mfc);
|
||||
const jsonStr = JSON.stringify(obj);
|
||||
ws.send(jsonStr);
|
||||
}
|
||||
};
|
||||
const ProtobufContentTypeHandler = {
|
||||
webSocketUrlPath: "/api/ws/send_receive_proto",
|
||||
sendMessageFromClient(mfc, ws) {
|
||||
const bytes = MessageFromClient.encode(mfc).finish();
|
||||
ws.send(bytes);
|
||||
}
|
||||
};
|
||||
export const ContentTypeHandler = {
|
||||
Json: JsonContentTypeHandler,
|
||||
Protobuf: ProtobufContentTypeHandler,
|
||||
};
|
||||
export function newHermesClient(rootUrl, contentTypeHandler) {
|
||||
const hci = new HermesClientImpl(rootUrl, contentTypeHandler);
|
||||
hci.mailbox().then((mbox) => {
|
||||
const correlations = hci.correlations;
|
||||
hci.channelMessageSubscribe({
|
||||
id: "rpc-inbox",
|
||||
state: "rpc-inbox",
|
||||
readerKey: mbox.readerKey,
|
||||
channel: "rpc-inbox",
|
||||
startSeq: "all"
|
||||
}, (me, msg) => {
|
||||
var _a, _b, _c, _d, _e, _f;
|
||||
if (me.messageBytes) {
|
||||
try {
|
||||
const msg = Message.decode(me.messageBytes);
|
||||
const endPoint = (_b = (_a = msg.header) === null || _a === void 0 ? void 0 : _a.rpcHeader) === null || _b === void 0 ? void 0 : _b.endPoint;
|
||||
if (((_d = (_c = msg.header) === null || _c === void 0 ? void 0 : _c.rpcHeader) === null || _d === void 0 ? void 0 : _d.frameType) === RpcFrameType.Request && endPoint == "ping") {
|
||||
hci.sendPongResponse(mbox, msg, endPoint);
|
||||
}
|
||||
else {
|
||||
const correlationId = (_f = (_e = msg.header) === null || _e === void 0 ? void 0 : _e.rpcHeader) === null || _f === void 0 ? void 0 : _f.correlationId;
|
||||
if (correlationId) {
|
||||
const resolve = correlations.get(correlationId);
|
||||
if (resolve !== undefined) {
|
||||
resolve(msg);
|
||||
}
|
||||
correlations.delete(correlationId);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
console.error("error decoding message", e);
|
||||
}
|
||||
}
|
||||
// noop since we are only interested in the correlationId for rpc and that happens in onMessage
|
||||
});
|
||||
});
|
||||
// send ping every 30 seconds
|
||||
setInterval(() => hci.sendPing(), 30 * 1000);
|
||||
return hci;
|
||||
}
|
||||
/**
|
||||
* Create the mailbox
|
||||
* @param channels
|
||||
* @param rootUrl
|
||||
* @returns
|
||||
*/
|
||||
async function createMailbox(channels, rootUrl) {
|
||||
const mbox = {
|
||||
channels: channels,
|
||||
privateMetadata: {},
|
||||
publicMetadata: {},
|
||||
purgeTimeoutInMillis: 0,
|
||||
closeTimeoutInMillis: 0,
|
||||
extraData: {},
|
||||
};
|
||||
const mboxObj = CreateMailboxRequest.toJSON(mbox);
|
||||
const mboxJson = JSON.stringify(mboxObj);
|
||||
let mailboxResponse = undefined;
|
||||
const response = await fetch(`${rootUrl}/api/create_mailbox`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: mboxJson,
|
||||
});
|
||||
if (response.ok) {
|
||||
const responseJsonStr = await response.text();
|
||||
mailboxResponse = CreateMailboxResponse.fromJSON(JSON.parse(responseJsonStr));
|
||||
}
|
||||
else {
|
||||
throw new Error(`createMailbox failed with status ${response.status}`);
|
||||
}
|
||||
return mailboxResponse;
|
||||
}
|
||||
class Constants {
|
||||
}
|
||||
Constants.rpcInboxChannelName = "rpc-inbox";
|
||||
Constants.rpcSentChannelName = "rpc-sent";
|
||||
class HermesConnection {
|
||||
constructor(clientImpl, mailbox, webSocket) {
|
||||
this.clientImpl = clientImpl;
|
||||
this.mailbox = mailbox;
|
||||
this.webSocket = webSocket;
|
||||
const self = this;
|
||||
webSocket.onmessage = function (event) {
|
||||
if (event.data instanceof ArrayBuffer) {
|
||||
self.onWebSocketBinaryMessage(event.data);
|
||||
}
|
||||
else {
|
||||
self.onWebSocketTextMessage(event.data);
|
||||
}
|
||||
};
|
||||
webSocket.onclose = function (event) {
|
||||
console.log("HermesConnection websocket closed", event);
|
||||
clientImpl.reconnect();
|
||||
};
|
||||
// resend un ack'ed messages
|
||||
clientImpl.sentMessagesWaitingForAck.forEach((smr, idempotentId) => {
|
||||
self.sendSendMessageRequest(smr, false);
|
||||
});
|
||||
}
|
||||
onWebSocketTextMessage(message) {
|
||||
const jsonObj = JSON.parse(message);
|
||||
const m2c = MessageToClient.fromJSON(jsonObj);
|
||||
this.onMessageToClient(m2c);
|
||||
}
|
||||
onWebSocketBinaryMessage(message) {
|
||||
const m2c = MessageToClient.decode(new Uint8Array(message));
|
||||
this.onMessageToClient(m2c);
|
||||
}
|
||||
onMessageToClient(m2c) {
|
||||
var _a, _b, _c;
|
||||
if (m2c.notification !== undefined) {
|
||||
console.log("hermes client received notification " + m2c.notification, m2c.notification);
|
||||
}
|
||||
else if (m2c.messageEnvelope !== undefined) {
|
||||
const me = m2c.messageEnvelope;
|
||||
if (me.messageBytes === undefined) {
|
||||
console.log("hermes client received empty messageEnvelope", m2c.messageEnvelope);
|
||||
}
|
||||
else {
|
||||
const subscriptionId = (_a = me.serverEnvelope) === null || _a === void 0 ? void 0 : _a.subscriptionId;
|
||||
if (subscriptionId) {
|
||||
const activeSub = this.clientImpl.activeSubscriptions.get(subscriptionId);
|
||||
if (activeSub) {
|
||||
const startSeq = (_b = me.serverEnvelope) === null || _b === void 0 ? void 0 : _b.sequence;
|
||||
if (startSeq) {
|
||||
activeSub.protoRawSubscription.startSeq = String(startSeq);
|
||||
}
|
||||
activeSub.onMessageEvent(me);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (m2c.sendMessageResponse !== undefined) {
|
||||
const id = (_c = m2c.sendMessageResponse) === null || _c === void 0 ? void 0 : _c.idempotentId;
|
||||
if (id) {
|
||||
this.clientImpl.sentMessagesWaitingForAck.delete(id);
|
||||
}
|
||||
console.log("hermes client received SendMessageResponse", m2c.sendMessageResponse);
|
||||
}
|
||||
else if (m2c.subscribeResponse !== undefined) {
|
||||
console.log("hermes client received subscribeResponse", m2c.subscribeResponse);
|
||||
}
|
||||
else if (m2c.ping !== undefined) {
|
||||
this.webSocket.send(JSON.stringify({ pong: {} }));
|
||||
}
|
||||
else if (m2c.pong !== undefined) {
|
||||
console.log("hermes client received pong");
|
||||
}
|
||||
}
|
||||
sendMessageFromClient(mfc) {
|
||||
console.log("sending websocket message", mfc);
|
||||
this.clientImpl.contentTypeHandler.sendMessageFromClient(mfc, this.webSocket);
|
||||
}
|
||||
addActiveSubscription(activeSub) {
|
||||
const listeners = this.clientImpl.activeSubscriptions.get(activeSub.subscriptionId);
|
||||
if (listeners) {
|
||||
throw Error(`subscriptionId ${activeSub.subscriptionId} is already subscribed`);
|
||||
}
|
||||
else {
|
||||
this.clientImpl.activeSubscriptions.set(activeSub.subscriptionId, activeSub);
|
||||
}
|
||||
}
|
||||
cdcSubscribe(cdcs, listener) {
|
||||
const subscriptionId = "cdc-" + cdcs.tables.map((t) => t.database + "." + t.table).join("-");
|
||||
const protoCdcs = {
|
||||
id: subscriptionId,
|
||||
matchers: cdcs.tables,
|
||||
startSeq: cdcs.startSeq,
|
||||
};
|
||||
this.sendMessageFromClient({ subscribeRequest: { subscriptions: [{ changeDataCapture: protoCdcs }] } });
|
||||
function onMessage(msg) {
|
||||
const json = new TextDecoder().decode(msg.messageBytes);
|
||||
const cdcEvent = JSON.parse(json);
|
||||
listener(cdcEvent, cdcEvent.data);
|
||||
}
|
||||
this.addActiveSubscription({
|
||||
subscriptionId: subscriptionId,
|
||||
protoRawSubscription: protoCdcs,
|
||||
onMessageEvent: onMessage,
|
||||
protoSubscription: { changeDataCapture: protoCdcs }
|
||||
});
|
||||
}
|
||||
channelMessageSubscribe(ms, listener) {
|
||||
this.rawChannelSubscribe(ms, Message.decode, listener);
|
||||
}
|
||||
channelSendReceiptSubscribe(ms, listener) {
|
||||
this.rawChannelSubscribe(ms, SendReceipt.decode, listener);
|
||||
}
|
||||
rawChannelSubscribe(ms, decoder, listener) {
|
||||
const subscriptionId = ms.id;
|
||||
if (!subscriptionId) {
|
||||
throw new Error("MailboxSubscription id is undefined");
|
||||
}
|
||||
function onMessage(msg) {
|
||||
if (msg.messageBytes === undefined) {
|
||||
console.error("MessageEnvelope.messageBytes is undefined");
|
||||
return;
|
||||
}
|
||||
const a = decoder(msg.messageBytes);
|
||||
listener(msg, a);
|
||||
}
|
||||
this.sendMessageFromClient({ subscribeRequest: { subscriptions: [{ mailbox: ms }] } });
|
||||
this.addActiveSubscription({
|
||||
subscriptionId: subscriptionId,
|
||||
onMessageEvent: onMessage,
|
||||
protoRawSubscription: ms,
|
||||
protoSubscription: { mailbox: ms }
|
||||
});
|
||||
}
|
||||
sendPing() {
|
||||
this.sendMessageFromClient({ ping: {} });
|
||||
}
|
||||
sendSendMessageRequest(smr, registerForAck) {
|
||||
if (registerForAck && smr.idempotentId) {
|
||||
this.clientImpl.sentMessagesWaitingForAck.set(smr.idempotentId, smr);
|
||||
}
|
||||
this.sendMessageFromClient({ sendMessageRequest: smr });
|
||||
}
|
||||
rawRpcCall(request) {
|
||||
var _a;
|
||||
const emptyBytes = new Uint8Array(0);
|
||||
const correlationId = ((_a = this.mailbox.address) !== null && _a !== void 0 ? _a : "") + "-" + this.clientImpl.correlationIdCounter++;
|
||||
const idempotentId = this.mailbox.address + correlationId;
|
||||
const smr = {
|
||||
channel: Constants.rpcInboxChannelName,
|
||||
to: [request.to],
|
||||
idempotentId: idempotentId,
|
||||
message: {
|
||||
header: {
|
||||
rpcHeader: {
|
||||
correlationId: correlationId,
|
||||
endPoint: request.endPoint,
|
||||
frameType: RpcFrameType.Request,
|
||||
errorInfo: undefined,
|
||||
},
|
||||
sender: this.mailbox.address,
|
||||
contentType: request.contentType,
|
||||
extraHeaders: request.headers,
|
||||
senderSequence: 0,
|
||||
},
|
||||
serverEnvelope: undefined,
|
||||
senderEnvelope: {
|
||||
created: Date.now(),
|
||||
},
|
||||
data: request.body !== undefined ? request.body : emptyBytes,
|
||||
},
|
||||
};
|
||||
const promise = new Promise((resolve, reject) => {
|
||||
this.clientImpl.correlations.set(correlationId, resolve);
|
||||
});
|
||||
this.sendSendMessageRequest(smr, true);
|
||||
return promise;
|
||||
}
|
||||
rpcObserverSubscribe(readerKey, listener) {
|
||||
console.log("rpcObserverSubscribe", readerKey);
|
||||
const correlations = new Map();
|
||||
const msInbox = {
|
||||
id: "rpc-inbox-" + readerKey,
|
||||
readerKey: readerKey,
|
||||
channel: "rpc-inbox",
|
||||
startSeq: "first",
|
||||
};
|
||||
this.channelMessageSubscribe(msInbox, (me, msg) => {
|
||||
var _a, _b;
|
||||
const correlationId = (_b = (_a = msg.header) === null || _a === void 0 ? void 0 : _a.rpcHeader) === null || _b === void 0 ? void 0 : _b.correlationId;
|
||||
if (correlationId) {
|
||||
var correlation = correlations.get(correlationId);
|
||||
if (!correlation) {
|
||||
correlation = new RpcRequestResponse(correlationId);
|
||||
correlations.set(correlationId, correlation);
|
||||
}
|
||||
correlation.inboxEnvelope = me;
|
||||
correlation.inboxMessage = msg;
|
||||
listener(correlation);
|
||||
}
|
||||
});
|
||||
const msSent = {
|
||||
id: "rpc-sent-" + readerKey,
|
||||
readerKey: readerKey,
|
||||
channel: "rpc-sent",
|
||||
startSeq: "first",
|
||||
};
|
||||
this.channelSendReceiptSubscribe(msSent, (me, sr) => {
|
||||
var _a, _b, _c, _d, _e;
|
||||
const msg = (_a = sr.request) === null || _a === void 0 ? void 0 : _a.message;
|
||||
const correlationId = (_e = (_d = (_c = (_b = sr.request) === null || _b === void 0 ? void 0 : _b.message) === null || _c === void 0 ? void 0 : _c.header) === null || _d === void 0 ? void 0 : _d.rpcHeader) === null || _e === void 0 ? void 0 : _e.correlationId;
|
||||
if (correlationId !== undefined) {
|
||||
var correlation = correlations.get(correlationId);
|
||||
if (correlation === undefined) {
|
||||
correlation = new RpcRequestResponse(correlationId);
|
||||
correlations.set(correlationId, correlation);
|
||||
}
|
||||
correlation.sentMessage = msg;
|
||||
correlation.sendReceiptEnvelope = me;
|
||||
correlation.sendReceipt = sr;
|
||||
listener(correlation);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
class HermesClientImpl {
|
||||
constructor(rootUrl, contentTypeHandler) {
|
||||
this.correlationIdCounter = 0;
|
||||
this.correlations = new Map();
|
||||
this.activeSubscriptions = new Map();
|
||||
this.sentMessagesWaitingForAck = new Map();
|
||||
const thisHermesClientImpl = this;
|
||||
this.rootUrl = rootUrl;
|
||||
this.contentTypeHandler = contentTypeHandler;
|
||||
this.mailboxResponseP = createMailbox([Constants.rpcInboxChannelName, Constants.rpcSentChannelName], rootUrl);
|
||||
var tempMailboxResponseP = this.mailboxResponseP;
|
||||
var tempWsUrl = new URL(rootUrl);
|
||||
tempWsUrl.protocol = tempWsUrl.protocol.replace("http", "ws");
|
||||
tempWsUrl.pathname = contentTypeHandler.webSocketUrlPath;
|
||||
this.wsUrl = tempWsUrl.toString();
|
||||
this.currentConn = this.newHermesConnection();
|
||||
}
|
||||
sendPongResponse(mbox, pingMsg, endPoint) {
|
||||
var _a, _b, _c, _d, _e, _f;
|
||||
const correlationId = (_b = (_a = pingMsg.header) === null || _a === void 0 ? void 0 : _a.rpcHeader) === null || _b === void 0 ? void 0 : _b.correlationId;
|
||||
const sender = (_c = pingMsg === null || pingMsg === void 0 ? void 0 : pingMsg.header) === null || _c === void 0 ? void 0 : _c.sender;
|
||||
const contentType = (_e = (_d = pingMsg === null || pingMsg === void 0 ? void 0 : pingMsg.header) === null || _d === void 0 ? void 0 : _d.contentType) !== null && _e !== void 0 ? _e : ContentType.UnspecifiedCT;
|
||||
if (correlationId !== undefined && sender !== undefined) {
|
||||
var ping = {};
|
||||
if (pingMsg.data !== undefined) {
|
||||
if (contentType == ContentType.Json) {
|
||||
ping = Ping.fromJSON(pingMsg.data);
|
||||
}
|
||||
else {
|
||||
ping = Ping.decode(pingMsg.data);
|
||||
}
|
||||
}
|
||||
const pong = { payload: ping.payload };
|
||||
var data;
|
||||
if (contentType == ContentType.Json) {
|
||||
data = new TextEncoder().encode(JSON.stringify(Pong.toJSON(pong)));
|
||||
}
|
||||
else {
|
||||
data = Pong.encode(pong).finish();
|
||||
}
|
||||
const idempotentId = mbox.address + correlationId;
|
||||
const smr = {
|
||||
channel: Constants.rpcInboxChannelName,
|
||||
to: [sender],
|
||||
idempotentId: idempotentId,
|
||||
message: {
|
||||
header: {
|
||||
rpcHeader: {
|
||||
correlationId: correlationId,
|
||||
endPoint: endPoint,
|
||||
frameType: RpcFrameType.SuccessResponse,
|
||||
errorInfo: undefined,
|
||||
},
|
||||
sender: mbox.address,
|
||||
contentType: (_f = pingMsg === null || pingMsg === void 0 ? void 0 : pingMsg.header) === null || _f === void 0 ? void 0 : _f.contentType,
|
||||
},
|
||||
serverEnvelope: undefined,
|
||||
senderEnvelope: {
|
||||
created: Date.now(),
|
||||
},
|
||||
data: data,
|
||||
},
|
||||
};
|
||||
this.withConn((conn) => {
|
||||
conn.sendSendMessageRequest(smr, true);
|
||||
});
|
||||
}
|
||||
else {
|
||||
console.log("ignoring ping no correlation id", pingMsg);
|
||||
}
|
||||
}
|
||||
reconnect() {
|
||||
this.currentConn = this.newHermesConnection();
|
||||
}
|
||||
newHermesConnection() {
|
||||
const outerThis = this;
|
||||
return new Promise((resolve, reject) => {
|
||||
this.mailboxResponseP.then((mbox) => {
|
||||
var webSocket = new WebSocket(this.wsUrl);
|
||||
webSocket.binaryType = "arraybuffer";
|
||||
webSocket.onopen = function (event) {
|
||||
console.log("hermes client websocket opened, sending first message");
|
||||
const resubscriptions = Object.values(outerThis.activeSubscriptions).map((as) => { return as.protoSubscription; });
|
||||
// send first message
|
||||
const firstMessage = {
|
||||
senderInfo: {
|
||||
readerKey: mbox.readerKey,
|
||||
address: mbox.address,
|
||||
},
|
||||
subscriptions: resubscriptions,
|
||||
mailboxTimeoutInMs: 2 * 60 * 1000, // 2 minutes
|
||||
};
|
||||
const mfc = {
|
||||
firstMessage: firstMessage,
|
||||
};
|
||||
console.log("sending first message");
|
||||
outerThis.contentTypeHandler.sendMessageFromClient(mfc, webSocket);
|
||||
console.log("resolving promise");
|
||||
resolve(new HermesConnection(outerThis, mbox, webSocket));
|
||||
};
|
||||
});
|
||||
});
|
||||
}
|
||||
mailbox() {
|
||||
return this.mailboxResponseP;
|
||||
}
|
||||
async withConn(fn) {
|
||||
return this.currentConn.then((conn) => fn(conn));
|
||||
}
|
||||
async withConnP(fn) {
|
||||
return this.currentConn.then((conn) => fn(conn));
|
||||
}
|
||||
rawRpcCall(request) {
|
||||
return this.withConnP((conn) => {
|
||||
return conn.rawRpcCall(request);
|
||||
});
|
||||
}
|
||||
cdcSubscribe(cdcs, listener) {
|
||||
this.withConn((conn) => {
|
||||
conn.cdcSubscribe(cdcs, listener);
|
||||
});
|
||||
}
|
||||
rpcObserverSubscribe(readerKey, listener) {
|
||||
console.log("outer rpcObserverSubscribe", readerKey);
|
||||
this.withConn((conn) => {
|
||||
console.log("inner rpcObserverSubscribe", readerKey);
|
||||
conn.rpcObserverSubscribe(readerKey, listener);
|
||||
});
|
||||
}
|
||||
channelMessageSubscribe(ms, listener) {
|
||||
this.withConn((conn) => {
|
||||
conn.channelMessageSubscribe(ms, listener);
|
||||
});
|
||||
}
|
||||
channelSendReceiptSubscribe(ms, listener) {
|
||||
this.withConn((conn) => {
|
||||
conn.channelSendReceiptSubscribe(ms, listener);
|
||||
});
|
||||
}
|
||||
sendPing() {
|
||||
this.withConn((conn) => {
|
||||
conn.sendPing();
|
||||
});
|
||||
}
|
||||
}
|
||||
export class RpcRequestResponse {
|
||||
constructor(correlationId) {
|
||||
this.correlationId = correlationId;
|
||||
}
|
||||
role() {
|
||||
const ic = this.isClient();
|
||||
if (ic) {
|
||||
return "client";
|
||||
}
|
||||
else if (ic === false) {
|
||||
return "server";
|
||||
}
|
||||
}
|
||||
contentType() {
|
||||
var _a, _b, _c, _d, _e, _f;
|
||||
const contentType = (_f = (_c = (_b = (_a = this.requestMessage()) === null || _a === void 0 ? void 0 : _a.header) === null || _b === void 0 ? void 0 : _b.contentType) !== null && _c !== void 0 ? _c : (_e = (_d = this.responseMessage()) === null || _d === void 0 ? void 0 : _d.header) === null || _e === void 0 ? void 0 : _e.contentType) !== null && _f !== void 0 ? _f : ContentType.UnspecifiedCT;
|
||||
return contentType;
|
||||
}
|
||||
isProtobuf() {
|
||||
return this.contentType() === ContentType.Protobuf;
|
||||
}
|
||||
isJson() {
|
||||
return this.contentType() === ContentType.Json;
|
||||
}
|
||||
isClient() {
|
||||
var _a, _b, _c, _d, _e, _f;
|
||||
const inboxFrameType = (_c = (_b = (_a = this.inboxMessage) === null || _a === void 0 ? void 0 : _a.header) === null || _b === void 0 ? void 0 : _b.rpcHeader) === null || _c === void 0 ? void 0 : _c.frameType;
|
||||
const sentFrameType = (_f = (_e = (_d = this.sentMessage) === null || _d === void 0 ? void 0 : _d.header) === null || _e === void 0 ? void 0 : _e.rpcHeader) === null || _f === void 0 ? void 0 : _f.frameType;
|
||||
if (sentFrameType === RpcFrameType.Request) {
|
||||
return true;
|
||||
}
|
||||
else if (inboxFrameType === RpcFrameType.Request) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
hasRequestAndResponse() {
|
||||
return this.sendReceiptEnvelope && this.inboxEnvelope ? true : false;
|
||||
}
|
||||
timeStarted() {
|
||||
var _a, _b, _c, _d;
|
||||
const ic = this.isClient();
|
||||
var time = undef();
|
||||
if (ic === true) {
|
||||
time = (_b = (_a = this.sendReceiptEnvelope) === null || _a === void 0 ? void 0 : _a.serverEnvelope) === null || _b === void 0 ? void 0 : _b.created;
|
||||
}
|
||||
else if (ic === false) {
|
||||
time = (_d = (_c = this.inboxEnvelope) === null || _c === void 0 ? void 0 : _c.serverEnvelope) === null || _d === void 0 ? void 0 : _d.created;
|
||||
}
|
||||
if (time) {
|
||||
return new Date(time);
|
||||
}
|
||||
}
|
||||
timeStartedL() {
|
||||
var _a, _b, _c, _d;
|
||||
const ic = this.isClient();
|
||||
var time = undef();
|
||||
if (ic === true) {
|
||||
time = (_b = (_a = this.sendReceiptEnvelope) === null || _a === void 0 ? void 0 : _a.serverEnvelope) === null || _b === void 0 ? void 0 : _b.created;
|
||||
}
|
||||
else if (ic === false) {
|
||||
time = (_d = (_c = this.inboxEnvelope) === null || _c === void 0 ? void 0 : _c.serverEnvelope) === null || _d === void 0 ? void 0 : _d.created;
|
||||
}
|
||||
return time;
|
||||
}
|
||||
timeCompleted() {
|
||||
var _a, _b, _c, _d;
|
||||
const ic = this.isClient();
|
||||
var time = undefined;
|
||||
if (ic === false) {
|
||||
time = (_b = (_a = this.sendReceiptEnvelope) === null || _a === void 0 ? void 0 : _a.serverEnvelope) === null || _b === void 0 ? void 0 : _b.created;
|
||||
}
|
||||
else if (ic === true) {
|
||||
time = (_d = (_c = this.inboxEnvelope) === null || _c === void 0 ? void 0 : _c.serverEnvelope) === null || _d === void 0 ? void 0 : _d.created;
|
||||
}
|
||||
if (time) {
|
||||
return new Date(time);
|
||||
}
|
||||
}
|
||||
durationInMillis() {
|
||||
var _a, _b;
|
||||
const ts = (_a = this.timeStarted()) === null || _a === void 0 ? void 0 : _a.getTime();
|
||||
const tc = (_b = this.timeCompleted()) === null || _b === void 0 ? void 0 : _b.getTime();
|
||||
if (ts && tc) {
|
||||
return tc - ts;
|
||||
}
|
||||
}
|
||||
endPoint() {
|
||||
var _a, _b, _c;
|
||||
return (_c = (_b = (_a = this.requestMessage()) === null || _a === void 0 ? void 0 : _a.header) === null || _b === void 0 ? void 0 : _b.rpcHeader) === null || _c === void 0 ? void 0 : _c.endPoint;
|
||||
}
|
||||
requestMessage() {
|
||||
const ic = this.isClient();
|
||||
if (ic === true) {
|
||||
return this.sentMessage;
|
||||
}
|
||||
else if (ic === false) {
|
||||
return this.inboxMessage;
|
||||
}
|
||||
}
|
||||
requestEnvelope() {
|
||||
const ic = this.isClient();
|
||||
if (ic === true) {
|
||||
return this.sendReceiptEnvelope;
|
||||
}
|
||||
else if (ic === false) {
|
||||
return this.inboxEnvelope;
|
||||
}
|
||||
}
|
||||
responseMessage() {
|
||||
const ic = this.isClient();
|
||||
if (ic === true) {
|
||||
return this.inboxMessage;
|
||||
}
|
||||
else if (ic === false) {
|
||||
return this.sentMessage;
|
||||
}
|
||||
}
|
||||
responseEnvelope() {
|
||||
const ic = this.isClient();
|
||||
if (ic === true) {
|
||||
return this.inboxEnvelope;
|
||||
}
|
||||
else if (ic === false) {
|
||||
return this.sendReceiptEnvelope;
|
||||
}
|
||||
}
|
||||
status() {
|
||||
var _a, _b, _c;
|
||||
const frameType = (_c = (_b = (_a = this.responseMessage()) === null || _a === void 0 ? void 0 : _a.header) === null || _b === void 0 ? void 0 : _b.rpcHeader) === null || _c === void 0 ? void 0 : _c.frameType;
|
||||
if (!frameType) {
|
||||
return "";
|
||||
}
|
||||
else if (frameType === RpcFrameType.ErrorResponse) {
|
||||
return "error";
|
||||
}
|
||||
else if (frameType === RpcFrameType.SuccessResponse) {
|
||||
return "success";
|
||||
}
|
||||
else {
|
||||
return `Unexpected frame types ${frameType}`;
|
||||
}
|
||||
}
|
||||
async processSchema(reqOrResp, data) {
|
||||
if (this.isJson()) {
|
||||
const jsonStr = new TextDecoder().decode(data);
|
||||
return JSON.parse(jsonStr);
|
||||
}
|
||||
else {
|
||||
const endPoint = this.endPoint();
|
||||
if (endPoint === undefined) {
|
||||
return {
|
||||
"error": "no endpoint"
|
||||
};
|
||||
}
|
||||
if (data === undefined) {
|
||||
return {};
|
||||
}
|
||||
return protobufToJson(endPoint, reqOrResp, data);
|
||||
}
|
||||
}
|
||||
async responseObj() {
|
||||
var _a;
|
||||
return this.processSchema("response", (_a = this.responseMessage()) === null || _a === void 0 ? void 0 : _a.data);
|
||||
}
|
||||
async requestObj() {
|
||||
var _a;
|
||||
return this.processSchema("request", (_a = this.requestMessage()) === null || _a === void 0 ? void 0 : _a.data);
|
||||
}
|
||||
}
|
||||
const GlobalClient = {
|
||||
get: memoize(() => newHermesClient("https://hermes-go.ahsrcm.com", JsonContentTypeHandler))
|
||||
};
|
||||
export default GlobalClient;
|
||||
export function runHermesClientTest() {
|
||||
}
|
||||
export function runHermesClientTest2() {
|
||||
// const hc = newHermesClient("https://hermes-go.ahsrcm.com", ContentType.Protobuf);
|
||||
const hc = newHermesClient("https://hermes-go.ahsrcm.com", JsonContentTypeHandler);
|
||||
hc.mailbox().then((mbox) => {
|
||||
const cdcs = {
|
||||
tables: [
|
||||
{
|
||||
database: "nefario",
|
||||
table: "service",
|
||||
},
|
||||
],
|
||||
startSeq: "new",
|
||||
};
|
||||
hc.cdcSubscribe(cdcs, (cdcEvent, a) => {
|
||||
console.log("cdcEvent", cdcEvent);
|
||||
});
|
||||
});
|
||||
// hc.correlatedRpcReader("rrb07167144dc644a0be22a85301afea7e" , (correlation) => {
|
||||
// console.log("correlation", correlation);
|
||||
// });
|
||||
}
|
||||
async function protobufToJson(schemaName, frametype, bytes) {
|
||||
// const mboxObj = CreateMailboxRequest.toJSON(mbox);
|
||||
// const mboxJson = JSON.stringify(mboxObj);
|
||||
// let mailboxResponse: CreateMailboxResponse | undefined = undefined;
|
||||
const rootUrl = GlobalClient.get().rootUrl;
|
||||
const response = await fetch(`${rootUrl}/api/proto_to_json?schema=${schemaName}&frametype=${frametype}`, {
|
||||
method: "POST",
|
||||
body: bytes,
|
||||
});
|
||||
if (response.ok) {
|
||||
const jsonStr = await response.text();
|
||||
return JSON.parse(jsonStr);
|
||||
}
|
||||
else {
|
||||
throw new Error(`proto_to_json failed with status ${response.status}`);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,201 @@
|
|||
import * as _m0 from "protobufjs/minimal";
|
||||
export declare const protobufPackage = "google.protobuf";
|
||||
/**
|
||||
* `NullValue` is a singleton enumeration to represent the null value for the
|
||||
* `Value` type union.
|
||||
*
|
||||
* The JSON representation for `NullValue` is JSON `null`.
|
||||
*/
|
||||
export declare enum NullValue {
|
||||
/** NULL_VALUE - Null value. */
|
||||
NULL_VALUE = 0,
|
||||
UNRECOGNIZED = -1
|
||||
}
|
||||
export declare function nullValueFromJSON(object: any): NullValue;
|
||||
export declare function nullValueToJSON(object: NullValue): string;
|
||||
/**
|
||||
* `Struct` represents a structured data value, consisting of fields
|
||||
* which map to dynamically typed values. In some languages, `Struct`
|
||||
* might be supported by a native representation. For example, in
|
||||
* scripting languages like JS a struct is represented as an
|
||||
* object. The details of that representation are described together
|
||||
* with the proto support for the language.
|
||||
*
|
||||
* The JSON representation for `Struct` is JSON object.
|
||||
*/
|
||||
export interface Struct {
|
||||
/** Unordered map of dynamically typed values. */
|
||||
fields: {
|
||||
[key: string]: any | undefined;
|
||||
};
|
||||
}
|
||||
export interface Struct_FieldsEntry {
|
||||
key: string;
|
||||
value: any | undefined;
|
||||
}
|
||||
/**
|
||||
* `Value` represents a dynamically typed value which can be either
|
||||
* null, a number, a string, a boolean, a recursive struct value, or a
|
||||
* list of values. A producer of value is expected to set one of these
|
||||
* variants. Absence of any variant indicates an error.
|
||||
*
|
||||
* The JSON representation for `Value` is JSON value.
|
||||
*/
|
||||
export interface Value {
|
||||
/** Represents a null value. */
|
||||
nullValue?: NullValue | undefined;
|
||||
/** Represents a double value. */
|
||||
numberValue?: number | undefined;
|
||||
/** Represents a string value. */
|
||||
stringValue?: string | undefined;
|
||||
/** Represents a boolean value. */
|
||||
boolValue?: boolean | undefined;
|
||||
/** Represents a structured value. */
|
||||
structValue?: {
|
||||
[key: string]: any;
|
||||
} | undefined;
|
||||
/** Represents a repeated `Value`. */
|
||||
listValue?: Array<any> | undefined;
|
||||
}
|
||||
/**
|
||||
* `ListValue` is a wrapper around a repeated field of values.
|
||||
*
|
||||
* The JSON representation for `ListValue` is JSON array.
|
||||
*/
|
||||
export interface ListValue {
|
||||
/** Repeated field of dynamically typed values. */
|
||||
values: any[];
|
||||
}
|
||||
export declare const Struct: {
|
||||
encode(message: Struct, writer?: _m0.Writer): _m0.Writer;
|
||||
decode(input: _m0.Reader | Uint8Array, length?: number): Struct;
|
||||
fromJSON(object: any): Struct;
|
||||
toJSON(message: Struct): unknown;
|
||||
create<I extends {
|
||||
fields?: {
|
||||
[x: string]: any;
|
||||
} | undefined;
|
||||
} & {
|
||||
fields?: ({
|
||||
[x: string]: any;
|
||||
} & {
|
||||
[x: string]: any;
|
||||
} & { [K in Exclude<keyof I["fields"], string | number>]: never; }) | undefined;
|
||||
} & { [K_1 in Exclude<keyof I, "fields">]: never; }>(base?: I): Struct;
|
||||
fromPartial<I_1 extends {
|
||||
fields?: {
|
||||
[x: string]: any;
|
||||
} | undefined;
|
||||
} & {
|
||||
fields?: ({
|
||||
[x: string]: any;
|
||||
} & {
|
||||
[x: string]: any;
|
||||
} & { [K_2 in Exclude<keyof I_1["fields"], string | number>]: never; }) | undefined;
|
||||
} & { [K_3 in Exclude<keyof I_1, "fields">]: never; }>(object: I_1): Struct;
|
||||
wrap(object: {
|
||||
[key: string]: any;
|
||||
} | undefined): Struct;
|
||||
unwrap(message: Struct): {
|
||||
[key: string]: any;
|
||||
};
|
||||
};
|
||||
export declare const Struct_FieldsEntry: {
|
||||
encode(message: Struct_FieldsEntry, writer?: _m0.Writer): _m0.Writer;
|
||||
decode(input: _m0.Reader | Uint8Array, length?: number): Struct_FieldsEntry;
|
||||
fromJSON(object: any): Struct_FieldsEntry;
|
||||
toJSON(message: Struct_FieldsEntry): unknown;
|
||||
create<I extends {
|
||||
key?: string | undefined;
|
||||
value?: any | undefined;
|
||||
} & {
|
||||
key?: string | undefined;
|
||||
value?: any | undefined;
|
||||
} & { [K in Exclude<keyof I, keyof Struct_FieldsEntry>]: never; }>(base?: I): Struct_FieldsEntry;
|
||||
fromPartial<I_1 extends {
|
||||
key?: string | undefined;
|
||||
value?: any | undefined;
|
||||
} & {
|
||||
key?: string | undefined;
|
||||
value?: any | undefined;
|
||||
} & { [K_1 in Exclude<keyof I_1, keyof Struct_FieldsEntry>]: never; }>(object: I_1): Struct_FieldsEntry;
|
||||
};
|
||||
export declare const Value: {
|
||||
encode(message: Value, writer?: _m0.Writer): _m0.Writer;
|
||||
decode(input: _m0.Reader | Uint8Array, length?: number): Value;
|
||||
fromJSON(object: any): Value;
|
||||
toJSON(message: Value): unknown;
|
||||
create<I extends {
|
||||
nullValue?: NullValue | undefined;
|
||||
numberValue?: number | undefined;
|
||||
stringValue?: string | undefined;
|
||||
boolValue?: boolean | undefined;
|
||||
structValue?: {
|
||||
[x: string]: any;
|
||||
} | undefined;
|
||||
listValue?: any[] | undefined;
|
||||
} & {
|
||||
nullValue?: NullValue | undefined;
|
||||
numberValue?: number | undefined;
|
||||
stringValue?: string | undefined;
|
||||
boolValue?: boolean | undefined;
|
||||
structValue?: ({
|
||||
[x: string]: any;
|
||||
} & {
|
||||
[x: string]: any;
|
||||
} & { [K in Exclude<keyof I["structValue"], string | number>]: never; }) | undefined;
|
||||
listValue?: (any[] & any[] & { [K_1 in Exclude<keyof I["listValue"], keyof any[]>]: never; }) | undefined;
|
||||
} & { [K_2 in Exclude<keyof I, keyof Value>]: never; }>(base?: I): Value;
|
||||
fromPartial<I_1 extends {
|
||||
nullValue?: NullValue | undefined;
|
||||
numberValue?: number | undefined;
|
||||
stringValue?: string | undefined;
|
||||
boolValue?: boolean | undefined;
|
||||
structValue?: {
|
||||
[x: string]: any;
|
||||
} | undefined;
|
||||
listValue?: any[] | undefined;
|
||||
} & {
|
||||
nullValue?: NullValue | undefined;
|
||||
numberValue?: number | undefined;
|
||||
stringValue?: string | undefined;
|
||||
boolValue?: boolean | undefined;
|
||||
structValue?: ({
|
||||
[x: string]: any;
|
||||
} & {
|
||||
[x: string]: any;
|
||||
} & { [K_3 in Exclude<keyof I_1["structValue"], string | number>]: never; }) | undefined;
|
||||
listValue?: (any[] & any[] & { [K_4 in Exclude<keyof I_1["listValue"], keyof any[]>]: never; }) | undefined;
|
||||
} & { [K_5 in Exclude<keyof I_1, keyof Value>]: never; }>(object: I_1): Value;
|
||||
wrap(value: any): Value;
|
||||
unwrap(message: any): string | number | boolean | Object | null | Array<any> | undefined;
|
||||
};
|
||||
export declare const ListValue: {
|
||||
encode(message: ListValue, writer?: _m0.Writer): _m0.Writer;
|
||||
decode(input: _m0.Reader | Uint8Array, length?: number): ListValue;
|
||||
fromJSON(object: any): ListValue;
|
||||
toJSON(message: ListValue): unknown;
|
||||
create<I extends {
|
||||
values?: any[] | undefined;
|
||||
} & {
|
||||
values?: (any[] & any[] & { [K in Exclude<keyof I["values"], keyof any[]>]: never; }) | undefined;
|
||||
} & { [K_1 in Exclude<keyof I, "values">]: never; }>(base?: I): ListValue;
|
||||
fromPartial<I_1 extends {
|
||||
values?: any[] | undefined;
|
||||
} & {
|
||||
values?: (any[] & any[] & { [K_2 in Exclude<keyof I_1["values"], keyof any[]>]: never; }) | undefined;
|
||||
} & { [K_3 in Exclude<keyof I_1, "values">]: never; }>(object: I_1): ListValue;
|
||||
wrap(array: Array<any> | undefined): ListValue;
|
||||
unwrap(message: ListValue): Array<any>;
|
||||
};
|
||||
type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined;
|
||||
export type DeepPartial<T> = T extends Builtin ? T : T extends globalThis.Array<infer U> ? globalThis.Array<DeepPartial<U>> : T extends ReadonlyArray<infer U> ? ReadonlyArray<DeepPartial<U>> : T extends {} ? {
|
||||
[K in keyof T]?: DeepPartial<T[K]>;
|
||||
} : Partial<T>;
|
||||
type KeysOfUnion<T> = T extends T ? keyof T : never;
|
||||
export type Exact<P, I extends P> = P extends Builtin ? P : P & {
|
||||
[K in keyof P]: Exact<P[K], I[K]>;
|
||||
} & {
|
||||
[K in Exclude<keyof I, KeysOfUnion<P>>]: never;
|
||||
};
|
||||
export {};
|
||||
|
|
@ -0,0 +1,441 @@
|
|||
/* eslint-disable */
|
||||
import * as _m0 from "protobufjs/minimal";
|
||||
export const protobufPackage = "google.protobuf";
|
||||
/**
|
||||
* `NullValue` is a singleton enumeration to represent the null value for the
|
||||
* `Value` type union.
|
||||
*
|
||||
* The JSON representation for `NullValue` is JSON `null`.
|
||||
*/
|
||||
export var NullValue;
|
||||
(function (NullValue) {
|
||||
/** NULL_VALUE - Null value. */
|
||||
NullValue[NullValue["NULL_VALUE"] = 0] = "NULL_VALUE";
|
||||
NullValue[NullValue["UNRECOGNIZED"] = -1] = "UNRECOGNIZED";
|
||||
})(NullValue || (NullValue = {}));
|
||||
export function nullValueFromJSON(object) {
|
||||
switch (object) {
|
||||
case 0:
|
||||
case "NULL_VALUE":
|
||||
return NullValue.NULL_VALUE;
|
||||
case -1:
|
||||
case "UNRECOGNIZED":
|
||||
default:
|
||||
return NullValue.UNRECOGNIZED;
|
||||
}
|
||||
}
|
||||
export function nullValueToJSON(object) {
|
||||
switch (object) {
|
||||
case NullValue.NULL_VALUE:
|
||||
return "NULL_VALUE";
|
||||
case NullValue.UNRECOGNIZED:
|
||||
default:
|
||||
return "UNRECOGNIZED";
|
||||
}
|
||||
}
|
||||
function createBaseStruct() {
|
||||
return { fields: {} };
|
||||
}
|
||||
export const Struct = {
|
||||
encode(message, writer = _m0.Writer.create()) {
|
||||
Object.entries(message.fields).forEach(([key, value]) => {
|
||||
if (value !== undefined) {
|
||||
Struct_FieldsEntry.encode({ key: key, value }, writer.uint32(10).fork()).ldelim();
|
||||
}
|
||||
});
|
||||
return writer;
|
||||
},
|
||||
decode(input, length) {
|
||||
const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseStruct();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
switch (tag >>> 3) {
|
||||
case 1:
|
||||
if (tag !== 10) {
|
||||
break;
|
||||
}
|
||||
const entry1 = Struct_FieldsEntry.decode(reader, reader.uint32());
|
||||
if (entry1.value !== undefined) {
|
||||
message.fields[entry1.key] = entry1.value;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if ((tag & 7) === 4 || tag === 0) {
|
||||
break;
|
||||
}
|
||||
reader.skipType(tag & 7);
|
||||
}
|
||||
return message;
|
||||
},
|
||||
fromJSON(object) {
|
||||
return {
|
||||
fields: isObject(object.fields)
|
||||
? Object.entries(object.fields).reduce((acc, [key, value]) => {
|
||||
acc[key] = value;
|
||||
return acc;
|
||||
}, {})
|
||||
: {},
|
||||
};
|
||||
},
|
||||
toJSON(message) {
|
||||
const obj = {};
|
||||
if (message.fields) {
|
||||
const entries = Object.entries(message.fields);
|
||||
if (entries.length > 0) {
|
||||
obj.fields = {};
|
||||
entries.forEach(([k, v]) => {
|
||||
obj.fields[k] = v;
|
||||
});
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
},
|
||||
create(base) {
|
||||
return Struct.fromPartial(base !== null && base !== void 0 ? base : {});
|
||||
},
|
||||
fromPartial(object) {
|
||||
var _a;
|
||||
const message = createBaseStruct();
|
||||
message.fields = Object.entries((_a = object.fields) !== null && _a !== void 0 ? _a : {}).reduce((acc, [key, value]) => {
|
||||
if (value !== undefined) {
|
||||
acc[key] = value;
|
||||
}
|
||||
return acc;
|
||||
}, {});
|
||||
return message;
|
||||
},
|
||||
wrap(object) {
|
||||
const struct = createBaseStruct();
|
||||
if (object !== undefined) {
|
||||
Object.keys(object).forEach((key) => {
|
||||
struct.fields[key] = object[key];
|
||||
});
|
||||
}
|
||||
return struct;
|
||||
},
|
||||
unwrap(message) {
|
||||
const object = {};
|
||||
if (message.fields) {
|
||||
Object.keys(message.fields).forEach((key) => {
|
||||
object[key] = message.fields[key];
|
||||
});
|
||||
}
|
||||
return object;
|
||||
},
|
||||
};
|
||||
function createBaseStruct_FieldsEntry() {
|
||||
return { key: "", value: undefined };
|
||||
}
|
||||
export const Struct_FieldsEntry = {
|
||||
encode(message, writer = _m0.Writer.create()) {
|
||||
if (message.key !== "") {
|
||||
writer.uint32(10).string(message.key);
|
||||
}
|
||||
if (message.value !== undefined) {
|
||||
Value.encode(Value.wrap(message.value), writer.uint32(18).fork()).ldelim();
|
||||
}
|
||||
return writer;
|
||||
},
|
||||
decode(input, length) {
|
||||
const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseStruct_FieldsEntry();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
switch (tag >>> 3) {
|
||||
case 1:
|
||||
if (tag !== 10) {
|
||||
break;
|
||||
}
|
||||
message.key = reader.string();
|
||||
continue;
|
||||
case 2:
|
||||
if (tag !== 18) {
|
||||
break;
|
||||
}
|
||||
message.value = Value.unwrap(Value.decode(reader, reader.uint32()));
|
||||
continue;
|
||||
}
|
||||
if ((tag & 7) === 4 || tag === 0) {
|
||||
break;
|
||||
}
|
||||
reader.skipType(tag & 7);
|
||||
}
|
||||
return message;
|
||||
},
|
||||
fromJSON(object) {
|
||||
return {
|
||||
key: isSet(object.key) ? globalThis.String(object.key) : "",
|
||||
value: isSet(object === null || object === void 0 ? void 0 : object.value) ? object.value : undefined,
|
||||
};
|
||||
},
|
||||
toJSON(message) {
|
||||
const obj = {};
|
||||
if (message.key !== "") {
|
||||
obj.key = message.key;
|
||||
}
|
||||
if (message.value !== undefined) {
|
||||
obj.value = message.value;
|
||||
}
|
||||
return obj;
|
||||
},
|
||||
create(base) {
|
||||
return Struct_FieldsEntry.fromPartial(base !== null && base !== void 0 ? base : {});
|
||||
},
|
||||
fromPartial(object) {
|
||||
var _a, _b;
|
||||
const message = createBaseStruct_FieldsEntry();
|
||||
message.key = (_a = object.key) !== null && _a !== void 0 ? _a : "";
|
||||
message.value = (_b = object.value) !== null && _b !== void 0 ? _b : undefined;
|
||||
return message;
|
||||
},
|
||||
};
|
||||
function createBaseValue() {
|
||||
return {
|
||||
nullValue: undefined,
|
||||
numberValue: undefined,
|
||||
stringValue: undefined,
|
||||
boolValue: undefined,
|
||||
structValue: undefined,
|
||||
listValue: undefined,
|
||||
};
|
||||
}
|
||||
export const Value = {
|
||||
encode(message, writer = _m0.Writer.create()) {
|
||||
if (message.nullValue !== undefined) {
|
||||
writer.uint32(8).int32(message.nullValue);
|
||||
}
|
||||
if (message.numberValue !== undefined) {
|
||||
writer.uint32(17).double(message.numberValue);
|
||||
}
|
||||
if (message.stringValue !== undefined) {
|
||||
writer.uint32(26).string(message.stringValue);
|
||||
}
|
||||
if (message.boolValue !== undefined) {
|
||||
writer.uint32(32).bool(message.boolValue);
|
||||
}
|
||||
if (message.structValue !== undefined) {
|
||||
Struct.encode(Struct.wrap(message.structValue), writer.uint32(42).fork()).ldelim();
|
||||
}
|
||||
if (message.listValue !== undefined) {
|
||||
ListValue.encode(ListValue.wrap(message.listValue), writer.uint32(50).fork()).ldelim();
|
||||
}
|
||||
return writer;
|
||||
},
|
||||
decode(input, length) {
|
||||
const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseValue();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
switch (tag >>> 3) {
|
||||
case 1:
|
||||
if (tag !== 8) {
|
||||
break;
|
||||
}
|
||||
message.nullValue = reader.int32();
|
||||
continue;
|
||||
case 2:
|
||||
if (tag !== 17) {
|
||||
break;
|
||||
}
|
||||
message.numberValue = reader.double();
|
||||
continue;
|
||||
case 3:
|
||||
if (tag !== 26) {
|
||||
break;
|
||||
}
|
||||
message.stringValue = reader.string();
|
||||
continue;
|
||||
case 4:
|
||||
if (tag !== 32) {
|
||||
break;
|
||||
}
|
||||
message.boolValue = reader.bool();
|
||||
continue;
|
||||
case 5:
|
||||
if (tag !== 42) {
|
||||
break;
|
||||
}
|
||||
message.structValue = Struct.unwrap(Struct.decode(reader, reader.uint32()));
|
||||
continue;
|
||||
case 6:
|
||||
if (tag !== 50) {
|
||||
break;
|
||||
}
|
||||
message.listValue = ListValue.unwrap(ListValue.decode(reader, reader.uint32()));
|
||||
continue;
|
||||
}
|
||||
if ((tag & 7) === 4 || tag === 0) {
|
||||
break;
|
||||
}
|
||||
reader.skipType(tag & 7);
|
||||
}
|
||||
return message;
|
||||
},
|
||||
fromJSON(object) {
|
||||
return {
|
||||
nullValue: isSet(object.nullValue) ? nullValueFromJSON(object.nullValue) : undefined,
|
||||
numberValue: isSet(object.numberValue) ? globalThis.Number(object.numberValue) : undefined,
|
||||
stringValue: isSet(object.stringValue) ? globalThis.String(object.stringValue) : undefined,
|
||||
boolValue: isSet(object.boolValue) ? globalThis.Boolean(object.boolValue) : undefined,
|
||||
structValue: isObject(object.structValue) ? object.structValue : undefined,
|
||||
listValue: globalThis.Array.isArray(object.listValue) ? [...object.listValue] : undefined,
|
||||
};
|
||||
},
|
||||
toJSON(message) {
|
||||
const obj = {};
|
||||
if (message.nullValue !== undefined) {
|
||||
obj.nullValue = nullValueToJSON(message.nullValue);
|
||||
}
|
||||
if (message.numberValue !== undefined) {
|
||||
obj.numberValue = message.numberValue;
|
||||
}
|
||||
if (message.stringValue !== undefined) {
|
||||
obj.stringValue = message.stringValue;
|
||||
}
|
||||
if (message.boolValue !== undefined) {
|
||||
obj.boolValue = message.boolValue;
|
||||
}
|
||||
if (message.structValue !== undefined) {
|
||||
obj.structValue = message.structValue;
|
||||
}
|
||||
if (message.listValue !== undefined) {
|
||||
obj.listValue = message.listValue;
|
||||
}
|
||||
return obj;
|
||||
},
|
||||
create(base) {
|
||||
return Value.fromPartial(base !== null && base !== void 0 ? base : {});
|
||||
},
|
||||
fromPartial(object) {
|
||||
var _a, _b, _c, _d, _e, _f;
|
||||
const message = createBaseValue();
|
||||
message.nullValue = (_a = object.nullValue) !== null && _a !== void 0 ? _a : undefined;
|
||||
message.numberValue = (_b = object.numberValue) !== null && _b !== void 0 ? _b : undefined;
|
||||
message.stringValue = (_c = object.stringValue) !== null && _c !== void 0 ? _c : undefined;
|
||||
message.boolValue = (_d = object.boolValue) !== null && _d !== void 0 ? _d : undefined;
|
||||
message.structValue = (_e = object.structValue) !== null && _e !== void 0 ? _e : undefined;
|
||||
message.listValue = (_f = object.listValue) !== null && _f !== void 0 ? _f : undefined;
|
||||
return message;
|
||||
},
|
||||
wrap(value) {
|
||||
const result = createBaseValue();
|
||||
if (value === null) {
|
||||
result.nullValue = NullValue.NULL_VALUE;
|
||||
}
|
||||
else if (typeof value === "boolean") {
|
||||
result.boolValue = value;
|
||||
}
|
||||
else if (typeof value === "number") {
|
||||
result.numberValue = value;
|
||||
}
|
||||
else if (typeof value === "string") {
|
||||
result.stringValue = value;
|
||||
}
|
||||
else if (globalThis.Array.isArray(value)) {
|
||||
result.listValue = value;
|
||||
}
|
||||
else if (typeof value === "object") {
|
||||
result.structValue = value;
|
||||
}
|
||||
else if (typeof value !== "undefined") {
|
||||
throw new globalThis.Error("Unsupported any value type: " + typeof value);
|
||||
}
|
||||
return result;
|
||||
},
|
||||
unwrap(message) {
|
||||
if (message.stringValue !== undefined) {
|
||||
return message.stringValue;
|
||||
}
|
||||
else if ((message === null || message === void 0 ? void 0 : message.numberValue) !== undefined) {
|
||||
return message.numberValue;
|
||||
}
|
||||
else if ((message === null || message === void 0 ? void 0 : message.boolValue) !== undefined) {
|
||||
return message.boolValue;
|
||||
}
|
||||
else if ((message === null || message === void 0 ? void 0 : message.structValue) !== undefined) {
|
||||
return message.structValue;
|
||||
}
|
||||
else if ((message === null || message === void 0 ? void 0 : message.listValue) !== undefined) {
|
||||
return message.listValue;
|
||||
}
|
||||
else if ((message === null || message === void 0 ? void 0 : message.nullValue) !== undefined) {
|
||||
return null;
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
};
|
||||
function createBaseListValue() {
|
||||
return { values: [] };
|
||||
}
|
||||
export const ListValue = {
|
||||
encode(message, writer = _m0.Writer.create()) {
|
||||
for (const v of message.values) {
|
||||
Value.encode(Value.wrap(v), writer.uint32(10).fork()).ldelim();
|
||||
}
|
||||
return writer;
|
||||
},
|
||||
decode(input, length) {
|
||||
const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseListValue();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
switch (tag >>> 3) {
|
||||
case 1:
|
||||
if (tag !== 10) {
|
||||
break;
|
||||
}
|
||||
message.values.push(Value.unwrap(Value.decode(reader, reader.uint32())));
|
||||
continue;
|
||||
}
|
||||
if ((tag & 7) === 4 || tag === 0) {
|
||||
break;
|
||||
}
|
||||
reader.skipType(tag & 7);
|
||||
}
|
||||
return message;
|
||||
},
|
||||
fromJSON(object) {
|
||||
return { values: globalThis.Array.isArray(object === null || object === void 0 ? void 0 : object.values) ? [...object.values] : [] };
|
||||
},
|
||||
toJSON(message) {
|
||||
var _a;
|
||||
const obj = {};
|
||||
if ((_a = message.values) === null || _a === void 0 ? void 0 : _a.length) {
|
||||
obj.values = message.values;
|
||||
}
|
||||
return obj;
|
||||
},
|
||||
create(base) {
|
||||
return ListValue.fromPartial(base !== null && base !== void 0 ? base : {});
|
||||
},
|
||||
fromPartial(object) {
|
||||
var _a;
|
||||
const message = createBaseListValue();
|
||||
message.values = ((_a = object.values) === null || _a === void 0 ? void 0 : _a.map((e) => e)) || [];
|
||||
return message;
|
||||
},
|
||||
wrap(array) {
|
||||
const result = createBaseListValue();
|
||||
result.values = array !== null && array !== void 0 ? array : [];
|
||||
return result;
|
||||
},
|
||||
unwrap(message) {
|
||||
if ((message === null || message === void 0 ? void 0 : message.hasOwnProperty("values")) && globalThis.Array.isArray(message.values)) {
|
||||
return message.values;
|
||||
}
|
||||
else {
|
||||
return message;
|
||||
}
|
||||
},
|
||||
};
|
||||
function isObject(value) {
|
||||
return typeof value === "object" && value !== null;
|
||||
}
|
||||
function isSet(value) {
|
||||
return value !== null && value !== undefined;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,16 @@
|
|||
#!/bin/sh
|
||||
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
||||
|
||||
case `uname` in
|
||||
*CYGWIN*|*MINGW*|*MSYS*)
|
||||
if command -v cygpath > /dev/null 2>&1; then
|
||||
basedir=`cygpath -w "$basedir"`
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -x "$basedir/node" ]; then
|
||||
exec "$basedir/node" "$basedir/../tsc/bin/tsc" "$@"
|
||||
else
|
||||
exec node "$basedir/../tsc/bin/tsc" "$@"
|
||||
fi
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
@ECHO off
|
||||
GOTO start
|
||||
:find_dp0
|
||||
SET dp0=%~dp0
|
||||
EXIT /b
|
||||
:start
|
||||
SETLOCAL
|
||||
CALL :find_dp0
|
||||
|
||||
IF EXIST "%dp0%\node.exe" (
|
||||
SET "_prog=%dp0%\node.exe"
|
||||
) ELSE (
|
||||
SET "_prog=node"
|
||||
SET PATHEXT=%PATHEXT:;.JS;=;%
|
||||
)
|
||||
|
||||
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\tsc\bin\tsc" %*
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
#!/usr/bin/env pwsh
|
||||
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
||||
|
||||
$exe=""
|
||||
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
||||
# Fix case when both the Windows and Linux builds of Node
|
||||
# are installed in the same directory
|
||||
$exe=".exe"
|
||||
}
|
||||
$ret=0
|
||||
if (Test-Path "$basedir/node$exe") {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "$basedir/node$exe" "$basedir/../tsc/bin/tsc" $args
|
||||
} else {
|
||||
& "$basedir/node$exe" "$basedir/../tsc/bin/tsc" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
} else {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "node$exe" "$basedir/../tsc/bin/tsc" $args
|
||||
} else {
|
||||
& "node$exe" "$basedir/../tsc/bin/tsc" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
}
|
||||
exit $ret
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
#!/bin/sh
|
||||
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
||||
|
||||
case `uname` in
|
||||
*CYGWIN*|*MINGW*|*MSYS*)
|
||||
if command -v cygpath > /dev/null 2>&1; then
|
||||
basedir=`cygpath -w "$basedir"`
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -x "$basedir/node" ]; then
|
||||
exec "$basedir/node" "$basedir/../typescript/bin/tsserver" "$@"
|
||||
else
|
||||
exec node "$basedir/../typescript/bin/tsserver" "$@"
|
||||
fi
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
@ECHO off
|
||||
GOTO start
|
||||
:find_dp0
|
||||
SET dp0=%~dp0
|
||||
EXIT /b
|
||||
:start
|
||||
SETLOCAL
|
||||
CALL :find_dp0
|
||||
|
||||
IF EXIST "%dp0%\node.exe" (
|
||||
SET "_prog=%dp0%\node.exe"
|
||||
) ELSE (
|
||||
SET "_prog=node"
|
||||
SET PATHEXT=%PATHEXT:;.JS;=;%
|
||||
)
|
||||
|
||||
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\typescript\bin\tsserver" %*
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
#!/usr/bin/env pwsh
|
||||
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
||||
|
||||
$exe=""
|
||||
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
||||
# Fix case when both the Windows and Linux builds of Node
|
||||
# are installed in the same directory
|
||||
$exe=".exe"
|
||||
}
|
||||
$ret=0
|
||||
if (Test-Path "$basedir/node$exe") {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "$basedir/node$exe" "$basedir/../typescript/bin/tsserver" $args
|
||||
} else {
|
||||
& "$basedir/node$exe" "$basedir/../typescript/bin/tsserver" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
} else {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "node$exe" "$basedir/../typescript/bin/tsserver" $args
|
||||
} else {
|
||||
& "node$exe" "$basedir/../typescript/bin/tsserver" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
}
|
||||
exit $ret
|
||||
|
|
@ -0,0 +1,138 @@
|
|||
{
|
||||
"name": "hermes-client",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"node_modules/@protobufjs/aspromise": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
|
||||
"integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ=="
|
||||
},
|
||||
"node_modules/@protobufjs/base64": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz",
|
||||
"integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg=="
|
||||
},
|
||||
"node_modules/@protobufjs/codegen": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz",
|
||||
"integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg=="
|
||||
},
|
||||
"node_modules/@protobufjs/eventemitter": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz",
|
||||
"integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q=="
|
||||
},
|
||||
"node_modules/@protobufjs/fetch": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz",
|
||||
"integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==",
|
||||
"dependencies": {
|
||||
"@protobufjs/aspromise": "^1.1.1",
|
||||
"@protobufjs/inquire": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@protobufjs/float": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz",
|
||||
"integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ=="
|
||||
},
|
||||
"node_modules/@protobufjs/inquire": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz",
|
||||
"integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q=="
|
||||
},
|
||||
"node_modules/@protobufjs/path": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz",
|
||||
"integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA=="
|
||||
},
|
||||
"node_modules/@protobufjs/pool": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz",
|
||||
"integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw=="
|
||||
},
|
||||
"node_modules/@protobufjs/utf8": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz",
|
||||
"integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw=="
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "20.12.12",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.12.tgz",
|
||||
"integrity": "sha512-eWLDGF/FOSPtAvEqeRAQ4C8LSA7M1I7i0ky1I8U7kD1J5ITyW3AsRhQrKVoWf5pFKZ2kILsEGJhsI9r93PYnOw==",
|
||||
"dependencies": {
|
||||
"undici-types": "~5.26.4"
|
||||
}
|
||||
},
|
||||
"node_modules/long": {
|
||||
"version": "5.2.3",
|
||||
"resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz",
|
||||
"integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q=="
|
||||
},
|
||||
"node_modules/protobufjs": {
|
||||
"version": "7.3.0",
|
||||
"resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.3.0.tgz",
|
||||
"integrity": "sha512-YWD03n3shzV9ImZRX3ccbjqLxj7NokGN0V/ESiBV5xWqrommYHYiihuIyavq03pWSGqlyvYUFmfoMKd+1rPA/g==",
|
||||
"hasInstallScript": true,
|
||||
"dependencies": {
|
||||
"@protobufjs/aspromise": "^1.1.2",
|
||||
"@protobufjs/base64": "^1.1.2",
|
||||
"@protobufjs/codegen": "^2.0.4",
|
||||
"@protobufjs/eventemitter": "^1.1.0",
|
||||
"@protobufjs/fetch": "^1.1.0",
|
||||
"@protobufjs/float": "^1.0.2",
|
||||
"@protobufjs/inquire": "^1.1.0",
|
||||
"@protobufjs/path": "^1.1.2",
|
||||
"@protobufjs/pool": "^1.1.0",
|
||||
"@protobufjs/utf8": "^1.1.0",
|
||||
"@types/node": ">=13.7.0",
|
||||
"long": "^5.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/rxjs": {
|
||||
"version": "7.8.1",
|
||||
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz",
|
||||
"integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==",
|
||||
"dependencies": {
|
||||
"tslib": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/tsc": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/tsc/-/tsc-2.0.4.tgz",
|
||||
"integrity": "sha512-fzoSieZI5KKJVBYGvwbVZs/J5za84f2lSTLPYf6AGiIf43tZ3GNrI1QzTLcjtyDDP4aLxd46RTZq1nQxe7+k5Q==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"tsc": "bin/tsc"
|
||||
}
|
||||
},
|
||||
"node_modules/tslib": {
|
||||
"version": "2.6.2",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
|
||||
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
|
||||
},
|
||||
"node_modules/typescript": {
|
||||
"version": "5.4.5",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz",
|
||||
"integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
"tsserver": "bin/tsserver"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.17"
|
||||
}
|
||||
},
|
||||
"node_modules/undici-types": {
|
||||
"version": "5.26.5",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
|
||||
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"systemParams": "win32-x64-115",
|
||||
"modulesFolders": [
|
||||
"node_modules"
|
||||
],
|
||||
"flags": [],
|
||||
"linkedModules": [],
|
||||
"topLevelPatterns": [
|
||||
"tsc@^2.0.4",
|
||||
"typescript@^5.4.5"
|
||||
],
|
||||
"lockfileEntries": {
|
||||
"tsc@^2.0.4": "https://registry.yarnpkg.com/tsc/-/tsc-2.0.4.tgz#5f6499146abea5dca4420b451fa4f2f9345238f5",
|
||||
"typescript@^5.4.5": "https://registry.yarnpkg.com/typescript/-/typescript-5.4.5.tgz#42ccef2c571fdbd0f6718b1d1f5e6e5ef006f611"
|
||||
},
|
||||
"files": [],
|
||||
"artifacts": {}
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
Copyright (c) 2016, Daniel Wirtz All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of its author, nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
@protobufjs/aspromise
|
||||
=====================
|
||||
[](https://www.npmjs.com/package/@protobufjs/aspromise)
|
||||
|
||||
Returns a promise from a node-style callback function.
|
||||
|
||||
API
|
||||
---
|
||||
|
||||
* **asPromise(fn: `function`, ctx: `Object`, ...params: `*`): `Promise<*>`**<br />
|
||||
Returns a promise from a node-style callback function.
|
||||
|
||||
**License:** [BSD 3-Clause License](https://opensource.org/licenses/BSD-3-Clause)
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
export = asPromise;
|
||||
|
||||
type asPromiseCallback = (error: Error | null, ...params: any[]) => {};
|
||||
|
||||
/**
|
||||
* Returns a promise from a node-style callback function.
|
||||
* @memberof util
|
||||
* @param {asPromiseCallback} fn Function to call
|
||||
* @param {*} ctx Function context
|
||||
* @param {...*} params Function arguments
|
||||
* @returns {Promise<*>} Promisified function
|
||||
*/
|
||||
declare function asPromise(fn: asPromiseCallback, ctx: any, ...params: any[]): Promise<any>;
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
"use strict";
|
||||
module.exports = asPromise;
|
||||
|
||||
/**
|
||||
* Callback as used by {@link util.asPromise}.
|
||||
* @typedef asPromiseCallback
|
||||
* @type {function}
|
||||
* @param {Error|null} error Error, if any
|
||||
* @param {...*} params Additional arguments
|
||||
* @returns {undefined}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Returns a promise from a node-style callback function.
|
||||
* @memberof util
|
||||
* @param {asPromiseCallback} fn Function to call
|
||||
* @param {*} ctx Function context
|
||||
* @param {...*} params Function arguments
|
||||
* @returns {Promise<*>} Promisified function
|
||||
*/
|
||||
function asPromise(fn, ctx/*, varargs */) {
|
||||
var params = new Array(arguments.length - 1),
|
||||
offset = 0,
|
||||
index = 2,
|
||||
pending = true;
|
||||
while (index < arguments.length)
|
||||
params[offset++] = arguments[index++];
|
||||
return new Promise(function executor(resolve, reject) {
|
||||
params[offset] = function callback(err/*, varargs */) {
|
||||
if (pending) {
|
||||
pending = false;
|
||||
if (err)
|
||||
reject(err);
|
||||
else {
|
||||
var params = new Array(arguments.length - 1),
|
||||
offset = 0;
|
||||
while (offset < params.length)
|
||||
params[offset++] = arguments[offset];
|
||||
resolve.apply(null, params);
|
||||
}
|
||||
}
|
||||
};
|
||||
try {
|
||||
fn.apply(ctx || null, params);
|
||||
} catch (err) {
|
||||
if (pending) {
|
||||
pending = false;
|
||||
reject(err);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"name": "@protobufjs/aspromise",
|
||||
"description": "Returns a promise from a node-style callback function.",
|
||||
"version": "1.1.2",
|
||||
"author": "Daniel Wirtz <dcode+protobufjs@dcode.io>",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/dcodeIO/protobuf.js.git"
|
||||
},
|
||||
"license": "BSD-3-Clause",
|
||||
"main": "index.js",
|
||||
"types": "index.d.ts",
|
||||
"devDependencies": {
|
||||
"istanbul": "^0.4.5",
|
||||
"tape": "^4.6.3"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "tape tests/*.js",
|
||||
"coverage": "istanbul cover node_modules/tape/bin/tape tests/*.js"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,130 @@
|
|||
var tape = require("tape");
|
||||
|
||||
var asPromise = require("..");
|
||||
|
||||
tape.test("aspromise", function(test) {
|
||||
|
||||
test.test(this.name + " - resolve", function(test) {
|
||||
|
||||
function fn(arg1, arg2, callback) {
|
||||
test.equal(this, ctx, "function should be called with this = ctx");
|
||||
test.equal(arg1, 1, "function should be called with arg1 = 1");
|
||||
test.equal(arg2, 2, "function should be called with arg2 = 2");
|
||||
callback(null, arg2);
|
||||
}
|
||||
|
||||
var ctx = {};
|
||||
|
||||
var promise = asPromise(fn, ctx, 1, 2);
|
||||
promise.then(function(arg2) {
|
||||
test.equal(arg2, 2, "promise should be resolved with arg2 = 2");
|
||||
test.end();
|
||||
}).catch(function(err) {
|
||||
test.fail("promise should not be rejected (" + err + ")");
|
||||
});
|
||||
});
|
||||
|
||||
test.test(this.name + " - reject", function(test) {
|
||||
|
||||
function fn(arg1, arg2, callback) {
|
||||
test.equal(this, ctx, "function should be called with this = ctx");
|
||||
test.equal(arg1, 1, "function should be called with arg1 = 1");
|
||||
test.equal(arg2, 2, "function should be called with arg2 = 2");
|
||||
callback(arg1);
|
||||
}
|
||||
|
||||
var ctx = {};
|
||||
|
||||
var promise = asPromise(fn, ctx, 1, 2);
|
||||
promise.then(function() {
|
||||
test.fail("promise should not be resolved");
|
||||
}).catch(function(err) {
|
||||
test.equal(err, 1, "promise should be rejected with err = 1");
|
||||
test.end();
|
||||
});
|
||||
});
|
||||
|
||||
test.test(this.name + " - resolve twice", function(test) {
|
||||
|
||||
function fn(arg1, arg2, callback) {
|
||||
test.equal(this, ctx, "function should be called with this = ctx");
|
||||
test.equal(arg1, 1, "function should be called with arg1 = 1");
|
||||
test.equal(arg2, 2, "function should be called with arg2 = 2");
|
||||
callback(null, arg2);
|
||||
callback(null, arg1);
|
||||
}
|
||||
|
||||
var ctx = {};
|
||||
var count = 0;
|
||||
|
||||
var promise = asPromise(fn, ctx, 1, 2);
|
||||
promise.then(function(arg2) {
|
||||
test.equal(arg2, 2, "promise should be resolved with arg2 = 2");
|
||||
if (++count > 1)
|
||||
test.fail("promise should not be resolved twice");
|
||||
test.end();
|
||||
}).catch(function(err) {
|
||||
test.fail("promise should not be rejected (" + err + ")");
|
||||
});
|
||||
});
|
||||
|
||||
test.test(this.name + " - reject twice", function(test) {
|
||||
|
||||
function fn(arg1, arg2, callback) {
|
||||
test.equal(this, ctx, "function should be called with this = ctx");
|
||||
test.equal(arg1, 1, "function should be called with arg1 = 1");
|
||||
test.equal(arg2, 2, "function should be called with arg2 = 2");
|
||||
callback(arg1);
|
||||
callback(arg2);
|
||||
}
|
||||
|
||||
var ctx = {};
|
||||
var count = 0;
|
||||
|
||||
var promise = asPromise(fn, ctx, 1, 2);
|
||||
promise.then(function() {
|
||||
test.fail("promise should not be resolved");
|
||||
}).catch(function(err) {
|
||||
test.equal(err, 1, "promise should be rejected with err = 1");
|
||||
if (++count > 1)
|
||||
test.fail("promise should not be rejected twice");
|
||||
test.end();
|
||||
});
|
||||
});
|
||||
|
||||
test.test(this.name + " - reject error", function(test) {
|
||||
|
||||
function fn(callback) {
|
||||
test.ok(arguments.length === 1 && typeof callback === "function", "function should be called with just a callback");
|
||||
throw 3;
|
||||
}
|
||||
|
||||
var promise = asPromise(fn, null);
|
||||
promise.then(function() {
|
||||
test.fail("promise should not be resolved");
|
||||
}).catch(function(err) {
|
||||
test.equal(err, 3, "promise should be rejected with err = 3");
|
||||
test.end();
|
||||
});
|
||||
});
|
||||
|
||||
test.test(this.name + " - reject and error", function(test) {
|
||||
|
||||
function fn(callback) {
|
||||
callback(3);
|
||||
throw 4;
|
||||
}
|
||||
|
||||
var count = 0;
|
||||
|
||||
var promise = asPromise(fn, null);
|
||||
promise.then(function() {
|
||||
test.fail("promise should not be resolved");
|
||||
}).catch(function(err) {
|
||||
test.equal(err, 3, "promise should be rejected with err = 3");
|
||||
if (++count > 1)
|
||||
test.fail("promise should not be rejected twice");
|
||||
test.end();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
Copyright (c) 2016, Daniel Wirtz All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of its author, nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
@protobufjs/base64
|
||||
==================
|
||||
[](https://www.npmjs.com/package/@protobufjs/base64)
|
||||
|
||||
A minimal base64 implementation for number arrays.
|
||||
|
||||
API
|
||||
---
|
||||
|
||||
* **base64.length(string: `string`): `number`**<br />
|
||||
Calculates the byte length of a base64 encoded string.
|
||||
|
||||
* **base64.encode(buffer: `Uint8Array`, start: `number`, end: `number`): `string`**<br />
|
||||
Encodes a buffer to a base64 encoded string.
|
||||
|
||||
* **base64.decode(string: `string`, buffer: `Uint8Array`, offset: `number`): `number`**<br />
|
||||
Decodes a base64 encoded string to a buffer.
|
||||
|
||||
**License:** [BSD 3-Clause License](https://opensource.org/licenses/BSD-3-Clause)
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
/**
|
||||
* Calculates the byte length of a base64 encoded string.
|
||||
* @param {string} string Base64 encoded string
|
||||
* @returns {number} Byte length
|
||||
*/
|
||||
export function length(string: string): number;
|
||||
|
||||
/**
|
||||
* Encodes a buffer to a base64 encoded string.
|
||||
* @param {Uint8Array} buffer Source buffer
|
||||
* @param {number} start Source start
|
||||
* @param {number} end Source end
|
||||
* @returns {string} Base64 encoded string
|
||||
*/
|
||||
export function encode(buffer: Uint8Array, start: number, end: number): string;
|
||||
|
||||
/**
|
||||
* Decodes a base64 encoded string to a buffer.
|
||||
* @param {string} string Source string
|
||||
* @param {Uint8Array} buffer Destination buffer
|
||||
* @param {number} offset Destination offset
|
||||
* @returns {number} Number of bytes written
|
||||
* @throws {Error} If encoding is invalid
|
||||
*/
|
||||
export function decode(string: string, buffer: Uint8Array, offset: number): number;
|
||||
|
||||
/**
|
||||
* Tests if the specified string appears to be base64 encoded.
|
||||
* @param {string} string String to test
|
||||
* @returns {boolean} `true` if it appears to be base64 encoded, otherwise false
|
||||
*/
|
||||
export function test(string: string): boolean;
|
||||
|
|
@ -0,0 +1,139 @@
|
|||
"use strict";
|
||||
|
||||
/**
|
||||
* A minimal base64 implementation for number arrays.
|
||||
* @memberof util
|
||||
* @namespace
|
||||
*/
|
||||
var base64 = exports;
|
||||
|
||||
/**
|
||||
* Calculates the byte length of a base64 encoded string.
|
||||
* @param {string} string Base64 encoded string
|
||||
* @returns {number} Byte length
|
||||
*/
|
||||
base64.length = function length(string) {
|
||||
var p = string.length;
|
||||
if (!p)
|
||||
return 0;
|
||||
var n = 0;
|
||||
while (--p % 4 > 1 && string.charAt(p) === "=")
|
||||
++n;
|
||||
return Math.ceil(string.length * 3) / 4 - n;
|
||||
};
|
||||
|
||||
// Base64 encoding table
|
||||
var b64 = new Array(64);
|
||||
|
||||
// Base64 decoding table
|
||||
var s64 = new Array(123);
|
||||
|
||||
// 65..90, 97..122, 48..57, 43, 47
|
||||
for (var i = 0; i < 64;)
|
||||
s64[b64[i] = i < 26 ? i + 65 : i < 52 ? i + 71 : i < 62 ? i - 4 : i - 59 | 43] = i++;
|
||||
|
||||
/**
|
||||
* Encodes a buffer to a base64 encoded string.
|
||||
* @param {Uint8Array} buffer Source buffer
|
||||
* @param {number} start Source start
|
||||
* @param {number} end Source end
|
||||
* @returns {string} Base64 encoded string
|
||||
*/
|
||||
base64.encode = function encode(buffer, start, end) {
|
||||
var parts = null,
|
||||
chunk = [];
|
||||
var i = 0, // output index
|
||||
j = 0, // goto index
|
||||
t; // temporary
|
||||
while (start < end) {
|
||||
var b = buffer[start++];
|
||||
switch (j) {
|
||||
case 0:
|
||||
chunk[i++] = b64[b >> 2];
|
||||
t = (b & 3) << 4;
|
||||
j = 1;
|
||||
break;
|
||||
case 1:
|
||||
chunk[i++] = b64[t | b >> 4];
|
||||
t = (b & 15) << 2;
|
||||
j = 2;
|
||||
break;
|
||||
case 2:
|
||||
chunk[i++] = b64[t | b >> 6];
|
||||
chunk[i++] = b64[b & 63];
|
||||
j = 0;
|
||||
break;
|
||||
}
|
||||
if (i > 8191) {
|
||||
(parts || (parts = [])).push(String.fromCharCode.apply(String, chunk));
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
if (j) {
|
||||
chunk[i++] = b64[t];
|
||||
chunk[i++] = 61;
|
||||
if (j === 1)
|
||||
chunk[i++] = 61;
|
||||
}
|
||||
if (parts) {
|
||||
if (i)
|
||||
parts.push(String.fromCharCode.apply(String, chunk.slice(0, i)));
|
||||
return parts.join("");
|
||||
}
|
||||
return String.fromCharCode.apply(String, chunk.slice(0, i));
|
||||
};
|
||||
|
||||
var invalidEncoding = "invalid encoding";
|
||||
|
||||
/**
|
||||
* Decodes a base64 encoded string to a buffer.
|
||||
* @param {string} string Source string
|
||||
* @param {Uint8Array} buffer Destination buffer
|
||||
* @param {number} offset Destination offset
|
||||
* @returns {number} Number of bytes written
|
||||
* @throws {Error} If encoding is invalid
|
||||
*/
|
||||
base64.decode = function decode(string, buffer, offset) {
|
||||
var start = offset;
|
||||
var j = 0, // goto index
|
||||
t; // temporary
|
||||
for (var i = 0; i < string.length;) {
|
||||
var c = string.charCodeAt(i++);
|
||||
if (c === 61 && j > 1)
|
||||
break;
|
||||
if ((c = s64[c]) === undefined)
|
||||
throw Error(invalidEncoding);
|
||||
switch (j) {
|
||||
case 0:
|
||||
t = c;
|
||||
j = 1;
|
||||
break;
|
||||
case 1:
|
||||
buffer[offset++] = t << 2 | (c & 48) >> 4;
|
||||
t = c;
|
||||
j = 2;
|
||||
break;
|
||||
case 2:
|
||||
buffer[offset++] = (t & 15) << 4 | (c & 60) >> 2;
|
||||
t = c;
|
||||
j = 3;
|
||||
break;
|
||||
case 3:
|
||||
buffer[offset++] = (t & 3) << 6 | c;
|
||||
j = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (j === 1)
|
||||
throw Error(invalidEncoding);
|
||||
return offset - start;
|
||||
};
|
||||
|
||||
/**
|
||||
* Tests if the specified string appears to be base64 encoded.
|
||||
* @param {string} string String to test
|
||||
* @returns {boolean} `true` if probably base64 encoded, otherwise false
|
||||
*/
|
||||
base64.test = function test(string) {
|
||||
return /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(string);
|
||||
};
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"name": "@protobufjs/base64",
|
||||
"description": "A minimal base64 implementation for number arrays.",
|
||||
"version": "1.1.2",
|
||||
"author": "Daniel Wirtz <dcode+protobufjs@dcode.io>",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/dcodeIO/protobuf.js.git"
|
||||
},
|
||||
"license": "BSD-3-Clause",
|
||||
"main": "index.js",
|
||||
"types": "index.d.ts",
|
||||
"devDependencies": {
|
||||
"istanbul": "^0.4.5",
|
||||
"tape": "^4.6.3"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "tape tests/*.js",
|
||||
"coverage": "istanbul cover node_modules/tape/bin/tape tests/*.js"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
var tape = require("tape");
|
||||
|
||||
var base64 = require("..");
|
||||
|
||||
var strings = {
|
||||
"": "",
|
||||
"a": "YQ==",
|
||||
"ab": "YWI=",
|
||||
"abcdefg": "YWJjZGVmZw==",
|
||||
"abcdefgh": "YWJjZGVmZ2g=",
|
||||
"abcdefghi": "YWJjZGVmZ2hp"
|
||||
};
|
||||
|
||||
tape.test("base64", function(test) {
|
||||
|
||||
Object.keys(strings).forEach(function(str) {
|
||||
var enc = strings[str];
|
||||
|
||||
test.equal(base64.test(enc), true, "should detect '" + enc + "' to be base64 encoded");
|
||||
|
||||
var len = base64.length(enc);
|
||||
test.equal(len, str.length, "should calculate '" + enc + "' as " + str.length + " bytes");
|
||||
|
||||
var buf = new Array(len);
|
||||
var len2 = base64.decode(enc, buf, 0);
|
||||
test.equal(len2, len, "should decode '" + enc + "' to " + len + " bytes");
|
||||
|
||||
test.equal(String.fromCharCode.apply(String, buf), str, "should decode '" + enc + "' to '" + str + "'");
|
||||
|
||||
var enc2 = base64.encode(buf, 0, buf.length);
|
||||
test.equal(enc2, enc, "should encode '" + str + "' to '" + enc + "'");
|
||||
|
||||
});
|
||||
|
||||
test.throws(function() {
|
||||
var buf = new Array(10);
|
||||
base64.decode("YQ!", buf, 0);
|
||||
}, Error, "should throw if encoding is invalid");
|
||||
|
||||
test.throws(function() {
|
||||
var buf = new Array(10);
|
||||
base64.decode("Y", buf, 0);
|
||||
}, Error, "should throw if string is truncated");
|
||||
|
||||
test.end();
|
||||
});
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
Copyright (c) 2016, Daniel Wirtz All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of its author, nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
@protobufjs/codegen
|
||||
===================
|
||||
[](https://www.npmjs.com/package/@protobufjs/codegen)
|
||||
|
||||
A minimalistic code generation utility.
|
||||
|
||||
API
|
||||
---
|
||||
|
||||
* **codegen([functionParams: `string[]`], [functionName: string]): `Codegen`**<br />
|
||||
Begins generating a function.
|
||||
|
||||
* **codegen.verbose = `false`**<br />
|
||||
When set to true, codegen will log generated code to console. Useful for debugging.
|
||||
|
||||
Invoking **codegen** returns an appender function that appends code to the function's body and returns itself:
|
||||
|
||||
* **Codegen(formatString: `string`, [...formatParams: `any`]): Codegen**<br />
|
||||
Appends code to the function's body. The format string can contain placeholders specifying the types of inserted format parameters:
|
||||
|
||||
* `%d`: Number (integer or floating point value)
|
||||
* `%f`: Floating point value
|
||||
* `%i`: Integer value
|
||||
* `%j`: JSON.stringify'ed value
|
||||
* `%s`: String value
|
||||
* `%%`: Percent sign<br />
|
||||
|
||||
* **Codegen([scope: `Object.<string,*>`]): `Function`**<br />
|
||||
Finishes the function and returns it.
|
||||
|
||||
* **Codegen.toString([functionNameOverride: `string`]): `string`**<br />
|
||||
Returns the function as a string.
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
```js
|
||||
var codegen = require("@protobufjs/codegen");
|
||||
|
||||
var add = codegen(["a", "b"], "add") // A function with parameters "a" and "b" named "add"
|
||||
("// awesome comment") // adds the line to the function's body
|
||||
("return a + b - c + %d", 1) // replaces %d with 1 and adds the line to the body
|
||||
({ c: 1 }); // adds "c" with a value of 1 to the function's scope
|
||||
|
||||
console.log(add.toString()); // function add(a, b) { return a + b - c + 1 }
|
||||
console.log(add(1, 2)); // calculates 1 + 2 - 1 + 1 = 3
|
||||
```
|
||||
|
||||
**License:** [BSD 3-Clause License](https://opensource.org/licenses/BSD-3-Clause)
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
export = codegen;
|
||||
|
||||
/**
|
||||
* Appends code to the function's body.
|
||||
* @param [formatStringOrScope] Format string or, to finish the function, an object of additional scope variables, if any
|
||||
* @param [formatParams] Format parameters
|
||||
* @returns Itself or the generated function if finished
|
||||
* @throws {Error} If format parameter counts do not match
|
||||
*/
|
||||
type Codegen = (formatStringOrScope?: (string|{ [k: string]: any }), ...formatParams: any[]) => (Codegen|Function);
|
||||
|
||||
/**
|
||||
* Begins generating a function.
|
||||
* @param functionParams Function parameter names
|
||||
* @param [functionName] Function name if not anonymous
|
||||
* @returns Appender that appends code to the function's body
|
||||
*/
|
||||
declare function codegen(functionParams: string[], functionName?: string): Codegen;
|
||||
|
||||
/**
|
||||
* Begins generating a function.
|
||||
* @param [functionName] Function name if not anonymous
|
||||
* @returns Appender that appends code to the function's body
|
||||
*/
|
||||
declare function codegen(functionName?: string): Codegen;
|
||||
|
||||
declare namespace codegen {
|
||||
|
||||
/** When set to `true`, codegen will log generated code to console. Useful for debugging. */
|
||||
let verbose: boolean;
|
||||
}
|
||||
|
|
@ -0,0 +1,99 @@
|
|||
"use strict";
|
||||
module.exports = codegen;
|
||||
|
||||
/**
|
||||
* Begins generating a function.
|
||||
* @memberof util
|
||||
* @param {string[]} functionParams Function parameter names
|
||||
* @param {string} [functionName] Function name if not anonymous
|
||||
* @returns {Codegen} Appender that appends code to the function's body
|
||||
*/
|
||||
function codegen(functionParams, functionName) {
|
||||
|
||||
/* istanbul ignore if */
|
||||
if (typeof functionParams === "string") {
|
||||
functionName = functionParams;
|
||||
functionParams = undefined;
|
||||
}
|
||||
|
||||
var body = [];
|
||||
|
||||
/**
|
||||
* Appends code to the function's body or finishes generation.
|
||||
* @typedef Codegen
|
||||
* @type {function}
|
||||
* @param {string|Object.<string,*>} [formatStringOrScope] Format string or, to finish the function, an object of additional scope variables, if any
|
||||
* @param {...*} [formatParams] Format parameters
|
||||
* @returns {Codegen|Function} Itself or the generated function if finished
|
||||
* @throws {Error} If format parameter counts do not match
|
||||
*/
|
||||
|
||||
function Codegen(formatStringOrScope) {
|
||||
// note that explicit array handling below makes this ~50% faster
|
||||
|
||||
// finish the function
|
||||
if (typeof formatStringOrScope !== "string") {
|
||||
var source = toString();
|
||||
if (codegen.verbose)
|
||||
console.log("codegen: " + source); // eslint-disable-line no-console
|
||||
source = "return " + source;
|
||||
if (formatStringOrScope) {
|
||||
var scopeKeys = Object.keys(formatStringOrScope),
|
||||
scopeParams = new Array(scopeKeys.length + 1),
|
||||
scopeValues = new Array(scopeKeys.length),
|
||||
scopeOffset = 0;
|
||||
while (scopeOffset < scopeKeys.length) {
|
||||
scopeParams[scopeOffset] = scopeKeys[scopeOffset];
|
||||
scopeValues[scopeOffset] = formatStringOrScope[scopeKeys[scopeOffset++]];
|
||||
}
|
||||
scopeParams[scopeOffset] = source;
|
||||
return Function.apply(null, scopeParams).apply(null, scopeValues); // eslint-disable-line no-new-func
|
||||
}
|
||||
return Function(source)(); // eslint-disable-line no-new-func
|
||||
}
|
||||
|
||||
// otherwise append to body
|
||||
var formatParams = new Array(arguments.length - 1),
|
||||
formatOffset = 0;
|
||||
while (formatOffset < formatParams.length)
|
||||
formatParams[formatOffset] = arguments[++formatOffset];
|
||||
formatOffset = 0;
|
||||
formatStringOrScope = formatStringOrScope.replace(/%([%dfijs])/g, function replace($0, $1) {
|
||||
var value = formatParams[formatOffset++];
|
||||
switch ($1) {
|
||||
case "d": case "f": return String(Number(value));
|
||||
case "i": return String(Math.floor(value));
|
||||
case "j": return JSON.stringify(value);
|
||||
case "s": return String(value);
|
||||
}
|
||||
return "%";
|
||||
});
|
||||
if (formatOffset !== formatParams.length)
|
||||
throw Error("parameter count mismatch");
|
||||
body.push(formatStringOrScope);
|
||||
return Codegen;
|
||||
}
|
||||
|
||||
function toString(functionNameOverride) {
|
||||
return "function " + (functionNameOverride || functionName || "") + "(" + (functionParams && functionParams.join(",") || "") + "){\n " + body.join("\n ") + "\n}";
|
||||
}
|
||||
|
||||
Codegen.toString = toString;
|
||||
return Codegen;
|
||||
}
|
||||
|
||||
/**
|
||||
* Begins generating a function.
|
||||
* @memberof util
|
||||
* @function codegen
|
||||
* @param {string} [functionName] Function name if not anonymous
|
||||
* @returns {Codegen} Appender that appends code to the function's body
|
||||
* @variation 2
|
||||
*/
|
||||
|
||||
/**
|
||||
* When set to `true`, codegen will log generated code to console. Useful for debugging.
|
||||
* @name util.codegen.verbose
|
||||
* @type {boolean}
|
||||
*/
|
||||
codegen.verbose = false;
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"name": "@protobufjs/codegen",
|
||||
"description": "A minimalistic code generation utility.",
|
||||
"version": "2.0.4",
|
||||
"author": "Daniel Wirtz <dcode+protobufjs@dcode.io>",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/dcodeIO/protobuf.js.git"
|
||||
},
|
||||
"license": "BSD-3-Clause",
|
||||
"main": "index.js",
|
||||
"types": "index.d.ts"
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
var codegen = require("..");
|
||||
|
||||
// new require("benchmark").Suite().add("add", function() {
|
||||
|
||||
var add = codegen(["a", "b"], "add")
|
||||
("// awesome comment")
|
||||
("return a + b - c + %d", 1)
|
||||
({ c: 1 });
|
||||
|
||||
if (add(1, 2) !== 3)
|
||||
throw Error("failed");
|
||||
|
||||
// }).on("cycle", function(event) { process.stdout.write(String(event.target) + "\n"); }).run();
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
Copyright (c) 2016, Daniel Wirtz All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of its author, nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
@protobufjs/eventemitter
|
||||
========================
|
||||
[](https://www.npmjs.com/package/@protobufjs/eventemitter)
|
||||
|
||||
A minimal event emitter.
|
||||
|
||||
API
|
||||
---
|
||||
|
||||
* **new EventEmitter()**<br />
|
||||
Constructs a new event emitter instance.
|
||||
|
||||
* **EventEmitter#on(evt: `string`, fn: `function`, [ctx: `Object`]): `EventEmitter`**<br />
|
||||
Registers an event listener.
|
||||
|
||||
* **EventEmitter#off([evt: `string`], [fn: `function`]): `EventEmitter`**<br />
|
||||
Removes an event listener or any matching listeners if arguments are omitted.
|
||||
|
||||
* **EventEmitter#emit(evt: `string`, ...args: `*`): `EventEmitter`**<br />
|
||||
Emits an event by calling its listeners with the specified arguments.
|
||||
|
||||
**License:** [BSD 3-Clause License](https://opensource.org/licenses/BSD-3-Clause)
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
export = EventEmitter;
|
||||
|
||||
/**
|
||||
* Constructs a new event emitter instance.
|
||||
* @classdesc A minimal event emitter.
|
||||
* @memberof util
|
||||
* @constructor
|
||||
*/
|
||||
declare class EventEmitter {
|
||||
|
||||
/**
|
||||
* Constructs a new event emitter instance.
|
||||
* @classdesc A minimal event emitter.
|
||||
* @memberof util
|
||||
* @constructor
|
||||
*/
|
||||
constructor();
|
||||
|
||||
/**
|
||||
* Registers an event listener.
|
||||
* @param {string} evt Event name
|
||||
* @param {function} fn Listener
|
||||
* @param {*} [ctx] Listener context
|
||||
* @returns {util.EventEmitter} `this`
|
||||
*/
|
||||
on(evt: string, fn: () => any, ctx?: any): EventEmitter;
|
||||
|
||||
/**
|
||||
* Removes an event listener or any matching listeners if arguments are omitted.
|
||||
* @param {string} [evt] Event name. Removes all listeners if omitted.
|
||||
* @param {function} [fn] Listener to remove. Removes all listeners of `evt` if omitted.
|
||||
* @returns {util.EventEmitter} `this`
|
||||
*/
|
||||
off(evt?: string, fn?: () => any): EventEmitter;
|
||||
|
||||
/**
|
||||
* Emits an event by calling its listeners with the specified arguments.
|
||||
* @param {string} evt Event name
|
||||
* @param {...*} args Arguments
|
||||
* @returns {util.EventEmitter} `this`
|
||||
*/
|
||||
emit(evt: string, ...args: any[]): EventEmitter;
|
||||
}
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
"use strict";
|
||||
module.exports = EventEmitter;
|
||||
|
||||
/**
|
||||
* Constructs a new event emitter instance.
|
||||
* @classdesc A minimal event emitter.
|
||||
* @memberof util
|
||||
* @constructor
|
||||
*/
|
||||
function EventEmitter() {
|
||||
|
||||
/**
|
||||
* Registered listeners.
|
||||
* @type {Object.<string,*>}
|
||||
* @private
|
||||
*/
|
||||
this._listeners = {};
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers an event listener.
|
||||
* @param {string} evt Event name
|
||||
* @param {function} fn Listener
|
||||
* @param {*} [ctx] Listener context
|
||||
* @returns {util.EventEmitter} `this`
|
||||
*/
|
||||
EventEmitter.prototype.on = function on(evt, fn, ctx) {
|
||||
(this._listeners[evt] || (this._listeners[evt] = [])).push({
|
||||
fn : fn,
|
||||
ctx : ctx || this
|
||||
});
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Removes an event listener or any matching listeners if arguments are omitted.
|
||||
* @param {string} [evt] Event name. Removes all listeners if omitted.
|
||||
* @param {function} [fn] Listener to remove. Removes all listeners of `evt` if omitted.
|
||||
* @returns {util.EventEmitter} `this`
|
||||
*/
|
||||
EventEmitter.prototype.off = function off(evt, fn) {
|
||||
if (evt === undefined)
|
||||
this._listeners = {};
|
||||
else {
|
||||
if (fn === undefined)
|
||||
this._listeners[evt] = [];
|
||||
else {
|
||||
var listeners = this._listeners[evt];
|
||||
for (var i = 0; i < listeners.length;)
|
||||
if (listeners[i].fn === fn)
|
||||
listeners.splice(i, 1);
|
||||
else
|
||||
++i;
|
||||
}
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Emits an event by calling its listeners with the specified arguments.
|
||||
* @param {string} evt Event name
|
||||
* @param {...*} args Arguments
|
||||
* @returns {util.EventEmitter} `this`
|
||||
*/
|
||||
EventEmitter.prototype.emit = function emit(evt) {
|
||||
var listeners = this._listeners[evt];
|
||||
if (listeners) {
|
||||
var args = [],
|
||||
i = 1;
|
||||
for (; i < arguments.length;)
|
||||
args.push(arguments[i++]);
|
||||
for (i = 0; i < listeners.length;)
|
||||
listeners[i].fn.apply(listeners[i++].ctx, args);
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"name": "@protobufjs/eventemitter",
|
||||
"description": "A minimal event emitter.",
|
||||
"version": "1.1.0",
|
||||
"author": "Daniel Wirtz <dcode+protobufjs@dcode.io>",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/dcodeIO/protobuf.js.git"
|
||||
},
|
||||
"license": "BSD-3-Clause",
|
||||
"main": "index.js",
|
||||
"types": "index.d.ts",
|
||||
"devDependencies": {
|
||||
"istanbul": "^0.4.5",
|
||||
"tape": "^4.6.3"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "tape tests/*.js",
|
||||
"coverage": "istanbul cover node_modules/tape/bin/tape tests/*.js"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
var tape = require("tape");
|
||||
|
||||
var EventEmitter = require("..");
|
||||
|
||||
tape.test("eventemitter", function(test) {
|
||||
|
||||
var ee = new EventEmitter();
|
||||
var fn;
|
||||
var ctx = {};
|
||||
|
||||
test.doesNotThrow(function() {
|
||||
ee.emit("a", 1);
|
||||
ee.off();
|
||||
ee.off("a");
|
||||
ee.off("a", function() {});
|
||||
}, "should not throw if no listeners are registered");
|
||||
|
||||
test.equal(ee.on("a", function(arg1) {
|
||||
test.equal(this, ctx, "should be called with this = ctx");
|
||||
test.equal(arg1, 1, "should be called with arg1 = 1");
|
||||
}, ctx), ee, "should return itself when registering events");
|
||||
ee.emit("a", 1);
|
||||
|
||||
ee.off("a");
|
||||
test.same(ee._listeners, { a: [] }, "should remove all listeners of the respective event when calling off(evt)");
|
||||
|
||||
ee.off();
|
||||
test.same(ee._listeners, {}, "should remove all listeners when just calling off()");
|
||||
|
||||
ee.on("a", fn = function(arg1) {
|
||||
test.equal(this, ctx, "should be called with this = ctx");
|
||||
test.equal(arg1, 1, "should be called with arg1 = 1");
|
||||
}, ctx).emit("a", 1);
|
||||
|
||||
ee.off("a", fn);
|
||||
test.same(ee._listeners, { a: [] }, "should remove the exact listener when calling off(evt, fn)");
|
||||
|
||||
ee.on("a", function() {
|
||||
test.equal(this, ee, "should be called with this = ee");
|
||||
}).emit("a");
|
||||
|
||||
test.doesNotThrow(function() {
|
||||
ee.off("a", fn);
|
||||
}, "should not throw if no such listener is found");
|
||||
|
||||
test.end();
|
||||
});
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
Copyright (c) 2016, Daniel Wirtz All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of its author, nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
@protobufjs/fetch
|
||||
=================
|
||||
[](https://www.npmjs.com/package/@protobufjs/fetch)
|
||||
|
||||
Fetches the contents of a file accross node and browsers.
|
||||
|
||||
API
|
||||
---
|
||||
|
||||
* **fetch(path: `string`, [options: { binary: boolean } ], [callback: `function(error: ?Error, [contents: string])`]): `Promise<string|Uint8Array>|undefined`**
|
||||
Fetches the contents of a file.
|
||||
|
||||
**License:** [BSD 3-Clause License](https://opensource.org/licenses/BSD-3-Clause)
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
export = fetch;
|
||||
|
||||
/**
|
||||
* Node-style callback as used by {@link util.fetch}.
|
||||
* @typedef FetchCallback
|
||||
* @type {function}
|
||||
* @param {?Error} error Error, if any, otherwise `null`
|
||||
* @param {string} [contents] File contents, if there hasn't been an error
|
||||
* @returns {undefined}
|
||||
*/
|
||||
type FetchCallback = (error: Error, contents?: string) => void;
|
||||
|
||||
/**
|
||||
* Options as used by {@link util.fetch}.
|
||||
* @typedef FetchOptions
|
||||
* @type {Object}
|
||||
* @property {boolean} [binary=false] Whether expecting a binary response
|
||||
* @property {boolean} [xhr=false] If `true`, forces the use of XMLHttpRequest
|
||||
*/
|
||||
|
||||
interface FetchOptions {
|
||||
binary?: boolean;
|
||||
xhr?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the contents of a file.
|
||||
* @memberof util
|
||||
* @param {string} filename File path or url
|
||||
* @param {FetchOptions} options Fetch options
|
||||
* @param {FetchCallback} callback Callback function
|
||||
* @returns {undefined}
|
||||
*/
|
||||
declare function fetch(filename: string, options: FetchOptions, callback: FetchCallback): void;
|
||||
|
||||
/**
|
||||
* Fetches the contents of a file.
|
||||
* @name util.fetch
|
||||
* @function
|
||||
* @param {string} path File path or url
|
||||
* @param {FetchCallback} callback Callback function
|
||||
* @returns {undefined}
|
||||
* @variation 2
|
||||
*/
|
||||
declare function fetch(path: string, callback: FetchCallback): void;
|
||||
|
||||
/**
|
||||
* Fetches the contents of a file.
|
||||
* @name util.fetch
|
||||
* @function
|
||||
* @param {string} path File path or url
|
||||
* @param {FetchOptions} [options] Fetch options
|
||||
* @returns {Promise<string|Uint8Array>} Promise
|
||||
* @variation 3
|
||||
*/
|
||||
declare function fetch(path: string, options?: FetchOptions): Promise<(string|Uint8Array)>;
|
||||
|
|
@ -0,0 +1,115 @@
|
|||
"use strict";
|
||||
module.exports = fetch;
|
||||
|
||||
var asPromise = require("@protobufjs/aspromise"),
|
||||
inquire = require("@protobufjs/inquire");
|
||||
|
||||
var fs = inquire("fs");
|
||||
|
||||
/**
|
||||
* Node-style callback as used by {@link util.fetch}.
|
||||
* @typedef FetchCallback
|
||||
* @type {function}
|
||||
* @param {?Error} error Error, if any, otherwise `null`
|
||||
* @param {string} [contents] File contents, if there hasn't been an error
|
||||
* @returns {undefined}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Options as used by {@link util.fetch}.
|
||||
* @typedef FetchOptions
|
||||
* @type {Object}
|
||||
* @property {boolean} [binary=false] Whether expecting a binary response
|
||||
* @property {boolean} [xhr=false] If `true`, forces the use of XMLHttpRequest
|
||||
*/
|
||||
|
||||
/**
|
||||
* Fetches the contents of a file.
|
||||
* @memberof util
|
||||
* @param {string} filename File path or url
|
||||
* @param {FetchOptions} options Fetch options
|
||||
* @param {FetchCallback} callback Callback function
|
||||
* @returns {undefined}
|
||||
*/
|
||||
function fetch(filename, options, callback) {
|
||||
if (typeof options === "function") {
|
||||
callback = options;
|
||||
options = {};
|
||||
} else if (!options)
|
||||
options = {};
|
||||
|
||||
if (!callback)
|
||||
return asPromise(fetch, this, filename, options); // eslint-disable-line no-invalid-this
|
||||
|
||||
// if a node-like filesystem is present, try it first but fall back to XHR if nothing is found.
|
||||
if (!options.xhr && fs && fs.readFile)
|
||||
return fs.readFile(filename, function fetchReadFileCallback(err, contents) {
|
||||
return err && typeof XMLHttpRequest !== "undefined"
|
||||
? fetch.xhr(filename, options, callback)
|
||||
: err
|
||||
? callback(err)
|
||||
: callback(null, options.binary ? contents : contents.toString("utf8"));
|
||||
});
|
||||
|
||||
// use the XHR version otherwise.
|
||||
return fetch.xhr(filename, options, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the contents of a file.
|
||||
* @name util.fetch
|
||||
* @function
|
||||
* @param {string} path File path or url
|
||||
* @param {FetchCallback} callback Callback function
|
||||
* @returns {undefined}
|
||||
* @variation 2
|
||||
*/
|
||||
|
||||
/**
|
||||
* Fetches the contents of a file.
|
||||
* @name util.fetch
|
||||
* @function
|
||||
* @param {string} path File path or url
|
||||
* @param {FetchOptions} [options] Fetch options
|
||||
* @returns {Promise<string|Uint8Array>} Promise
|
||||
* @variation 3
|
||||
*/
|
||||
|
||||
/**/
|
||||
fetch.xhr = function fetch_xhr(filename, options, callback) {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.onreadystatechange /* works everywhere */ = function fetchOnReadyStateChange() {
|
||||
|
||||
if (xhr.readyState !== 4)
|
||||
return undefined;
|
||||
|
||||
// local cors security errors return status 0 / empty string, too. afaik this cannot be
|
||||
// reliably distinguished from an actually empty file for security reasons. feel free
|
||||
// to send a pull request if you are aware of a solution.
|
||||
if (xhr.status !== 0 && xhr.status !== 200)
|
||||
return callback(Error("status " + xhr.status));
|
||||
|
||||
// if binary data is expected, make sure that some sort of array is returned, even if
|
||||
// ArrayBuffers are not supported. the binary string fallback, however, is unsafe.
|
||||
if (options.binary) {
|
||||
var buffer = xhr.response;
|
||||
if (!buffer) {
|
||||
buffer = [];
|
||||
for (var i = 0; i < xhr.responseText.length; ++i)
|
||||
buffer.push(xhr.responseText.charCodeAt(i) & 255);
|
||||
}
|
||||
return callback(null, typeof Uint8Array !== "undefined" ? new Uint8Array(buffer) : buffer);
|
||||
}
|
||||
return callback(null, xhr.responseText);
|
||||
};
|
||||
|
||||
if (options.binary) {
|
||||
// ref: https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Sending_and_Receiving_Binary_Data#Receiving_binary_data_in_older_browsers
|
||||
if ("overrideMimeType" in xhr)
|
||||
xhr.overrideMimeType("text/plain; charset=x-user-defined");
|
||||
xhr.responseType = "arraybuffer";
|
||||
}
|
||||
|
||||
xhr.open("GET", filename);
|
||||
xhr.send();
|
||||
};
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"name": "@protobufjs/fetch",
|
||||
"description": "Fetches the contents of a file accross node and browsers.",
|
||||
"version": "1.1.0",
|
||||
"author": "Daniel Wirtz <dcode+protobufjs@dcode.io>",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/dcodeIO/protobuf.js.git"
|
||||
},
|
||||
"dependencies": {
|
||||
"@protobufjs/aspromise": "^1.1.1",
|
||||
"@protobufjs/inquire": "^1.1.0"
|
||||
},
|
||||
"license": "BSD-3-Clause",
|
||||
"main": "index.js",
|
||||
"types": "index.d.ts",
|
||||
"devDependencies": {
|
||||
"istanbul": "^0.4.5",
|
||||
"tape": "^4.6.3"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "tape tests/*.js",
|
||||
"coverage": "istanbul cover node_modules/tape/bin/tape tests/*.js"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
var tape = require("tape");
|
||||
|
||||
var fetch = require("..");
|
||||
|
||||
tape.test("fetch", function(test) {
|
||||
|
||||
if (typeof Promise !== "undefined") {
|
||||
var promise = fetch("NOTFOUND");
|
||||
promise.catch(function() {});
|
||||
test.ok(promise instanceof Promise, "should return a promise if callback has been omitted");
|
||||
}
|
||||
|
||||
// TODO - some way to test this properly?
|
||||
|
||||
test.end();
|
||||
});
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
Copyright (c) 2016, Daniel Wirtz All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of its author, nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
|
@ -0,0 +1,102 @@
|
|||
@protobufjs/float
|
||||
=================
|
||||
[](https://www.npmjs.com/package/@protobufjs/float)
|
||||
|
||||
Reads / writes floats / doubles from / to buffers in both modern and ancient browsers. Fast.
|
||||
|
||||
API
|
||||
---
|
||||
|
||||
* **writeFloatLE(val: `number`, buf: `Uint8Array`, pos: `number`)**<br />
|
||||
Writes a 32 bit float to a buffer using little endian byte order.
|
||||
|
||||
* **writeFloatBE(val: `number`, buf: `Uint8Array`, pos: `number`)**<br />
|
||||
Writes a 32 bit float to a buffer using big endian byte order.
|
||||
|
||||
* **readFloatLE(buf: `Uint8Array`, pos: `number`): `number`**<br />
|
||||
Reads a 32 bit float from a buffer using little endian byte order.
|
||||
|
||||
* **readFloatBE(buf: `Uint8Array`, pos: `number`): `number`**<br />
|
||||
Reads a 32 bit float from a buffer using big endian byte order.
|
||||
|
||||
* **writeDoubleLE(val: `number`, buf: `Uint8Array`, pos: `number`)**<br />
|
||||
Writes a 64 bit double to a buffer using little endian byte order.
|
||||
|
||||
* **writeDoubleBE(val: `number`, buf: `Uint8Array`, pos: `number`)**<br />
|
||||
Writes a 64 bit double to a buffer using big endian byte order.
|
||||
|
||||
* **readDoubleLE(buf: `Uint8Array`, pos: `number`): `number`**<br />
|
||||
Reads a 64 bit double from a buffer using little endian byte order.
|
||||
|
||||
* **readDoubleBE(buf: `Uint8Array`, pos: `number`): `number`**<br />
|
||||
Reads a 64 bit double from a buffer using big endian byte order.
|
||||
|
||||
Performance
|
||||
-----------
|
||||
There is a simple benchmark included comparing raw read/write performance of this library (float), float's fallback for old browsers, the [ieee754](https://www.npmjs.com/package/ieee754) module and node's [buffer](https://nodejs.org/api/buffer.html). On an i7-2600k running node 6.9.1 it yields:
|
||||
|
||||
```
|
||||
benchmarking writeFloat performance ...
|
||||
|
||||
float x 42,741,625 ops/sec ±1.75% (81 runs sampled)
|
||||
float (fallback) x 11,272,532 ops/sec ±1.12% (85 runs sampled)
|
||||
ieee754 x 8,653,337 ops/sec ±1.18% (84 runs sampled)
|
||||
buffer x 12,412,414 ops/sec ±1.41% (83 runs sampled)
|
||||
buffer (noAssert) x 13,471,149 ops/sec ±1.09% (84 runs sampled)
|
||||
|
||||
float was fastest
|
||||
float (fallback) was 73.5% slower
|
||||
ieee754 was 79.6% slower
|
||||
buffer was 70.9% slower
|
||||
buffer (noAssert) was 68.3% slower
|
||||
|
||||
benchmarking readFloat performance ...
|
||||
|
||||
float x 44,382,729 ops/sec ±1.70% (84 runs sampled)
|
||||
float (fallback) x 20,925,938 ops/sec ±0.86% (87 runs sampled)
|
||||
ieee754 x 17,189,009 ops/sec ±1.01% (87 runs sampled)
|
||||
buffer x 10,518,437 ops/sec ±1.04% (83 runs sampled)
|
||||
buffer (noAssert) x 11,031,636 ops/sec ±1.15% (87 runs sampled)
|
||||
|
||||
float was fastest
|
||||
float (fallback) was 52.5% slower
|
||||
ieee754 was 61.0% slower
|
||||
buffer was 76.1% slower
|
||||
buffer (noAssert) was 75.0% slower
|
||||
|
||||
benchmarking writeDouble performance ...
|
||||
|
||||
float x 38,624,906 ops/sec ±0.93% (83 runs sampled)
|
||||
float (fallback) x 10,457,811 ops/sec ±1.54% (85 runs sampled)
|
||||
ieee754 x 7,681,130 ops/sec ±1.11% (83 runs sampled)
|
||||
buffer x 12,657,876 ops/sec ±1.03% (83 runs sampled)
|
||||
buffer (noAssert) x 13,372,795 ops/sec ±0.84% (85 runs sampled)
|
||||
|
||||
float was fastest
|
||||
float (fallback) was 73.1% slower
|
||||
ieee754 was 80.1% slower
|
||||
buffer was 67.3% slower
|
||||
buffer (noAssert) was 65.3% slower
|
||||
|
||||
benchmarking readDouble performance ...
|
||||
|
||||
float x 40,527,888 ops/sec ±1.05% (84 runs sampled)
|
||||
float (fallback) x 18,696,480 ops/sec ±0.84% (86 runs sampled)
|
||||
ieee754 x 14,074,028 ops/sec ±1.04% (87 runs sampled)
|
||||
buffer x 10,092,367 ops/sec ±1.15% (84 runs sampled)
|
||||
buffer (noAssert) x 10,623,793 ops/sec ±0.96% (84 runs sampled)
|
||||
|
||||
float was fastest
|
||||
float (fallback) was 53.8% slower
|
||||
ieee754 was 65.3% slower
|
||||
buffer was 75.1% slower
|
||||
buffer (noAssert) was 73.8% slower
|
||||
```
|
||||
|
||||
To run it yourself:
|
||||
|
||||
```
|
||||
$> npm run bench
|
||||
```
|
||||
|
||||
**License:** [BSD 3-Clause License](https://opensource.org/licenses/BSD-3-Clause)
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
"use strict";
|
||||
|
||||
var float = require(".."),
|
||||
ieee754 = require("ieee754"),
|
||||
newSuite = require("./suite");
|
||||
|
||||
var F32 = Float32Array;
|
||||
var F64 = Float64Array;
|
||||
delete global.Float32Array;
|
||||
delete global.Float64Array;
|
||||
var floatFallback = float({});
|
||||
global.Float32Array = F32;
|
||||
global.Float64Array = F64;
|
||||
|
||||
var buf = new Buffer(8);
|
||||
|
||||
newSuite("writeFloat")
|
||||
.add("float", function() {
|
||||
float.writeFloatLE(0.1, buf, 0);
|
||||
})
|
||||
.add("float (fallback)", function() {
|
||||
floatFallback.writeFloatLE(0.1, buf, 0);
|
||||
})
|
||||
.add("ieee754", function() {
|
||||
ieee754.write(buf, 0.1, 0, true, 23, 4);
|
||||
})
|
||||
.add("buffer", function() {
|
||||
buf.writeFloatLE(0.1, 0);
|
||||
})
|
||||
.add("buffer (noAssert)", function() {
|
||||
buf.writeFloatLE(0.1, 0, true);
|
||||
})
|
||||
.run();
|
||||
|
||||
newSuite("readFloat")
|
||||
.add("float", function() {
|
||||
float.readFloatLE(buf, 0);
|
||||
})
|
||||
.add("float (fallback)", function() {
|
||||
floatFallback.readFloatLE(buf, 0);
|
||||
})
|
||||
.add("ieee754", function() {
|
||||
ieee754.read(buf, 0, true, 23, 4);
|
||||
})
|
||||
.add("buffer", function() {
|
||||
buf.readFloatLE(0);
|
||||
})
|
||||
.add("buffer (noAssert)", function() {
|
||||
buf.readFloatLE(0, true);
|
||||
})
|
||||
.run();
|
||||
|
||||
newSuite("writeDouble")
|
||||
.add("float", function() {
|
||||
float.writeDoubleLE(0.1, buf, 0);
|
||||
})
|
||||
.add("float (fallback)", function() {
|
||||
floatFallback.writeDoubleLE(0.1, buf, 0);
|
||||
})
|
||||
.add("ieee754", function() {
|
||||
ieee754.write(buf, 0.1, 0, true, 52, 8);
|
||||
})
|
||||
.add("buffer", function() {
|
||||
buf.writeDoubleLE(0.1, 0);
|
||||
})
|
||||
.add("buffer (noAssert)", function() {
|
||||
buf.writeDoubleLE(0.1, 0, true);
|
||||
})
|
||||
.run();
|
||||
|
||||
newSuite("readDouble")
|
||||
.add("float", function() {
|
||||
float.readDoubleLE(buf, 0);
|
||||
})
|
||||
.add("float (fallback)", function() {
|
||||
floatFallback.readDoubleLE(buf, 0);
|
||||
})
|
||||
.add("ieee754", function() {
|
||||
ieee754.read(buf, 0, true, 52, 8);
|
||||
})
|
||||
.add("buffer", function() {
|
||||
buf.readDoubleLE(0);
|
||||
})
|
||||
.add("buffer (noAssert)", function() {
|
||||
buf.readDoubleLE(0, true);
|
||||
})
|
||||
.run();
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
"use strict";
|
||||
module.exports = newSuite;
|
||||
|
||||
var benchmark = require("benchmark"),
|
||||
chalk = require("chalk");
|
||||
|
||||
var padSize = 27;
|
||||
|
||||
function newSuite(name) {
|
||||
var benches = [];
|
||||
return new benchmark.Suite(name)
|
||||
.on("add", function(event) {
|
||||
benches.push(event.target);
|
||||
})
|
||||
.on("start", function() {
|
||||
process.stdout.write("benchmarking " + name + " performance ...\n\n");
|
||||
})
|
||||
.on("cycle", function(event) {
|
||||
process.stdout.write(String(event.target) + "\n");
|
||||
})
|
||||
.on("complete", function() {
|
||||
if (benches.length > 1) {
|
||||
var fastest = this.filter("fastest"), // eslint-disable-line no-invalid-this
|
||||
fastestHz = getHz(fastest[0]);
|
||||
process.stdout.write("\n" + chalk.white(pad(fastest[0].name, padSize)) + " was " + chalk.green("fastest") + "\n");
|
||||
benches.forEach(function(bench) {
|
||||
if (fastest.indexOf(bench) === 0)
|
||||
return;
|
||||
var hz = hz = getHz(bench);
|
||||
var percent = (1 - hz / fastestHz) * 100;
|
||||
process.stdout.write(chalk.white(pad(bench.name, padSize)) + " was " + chalk.red(percent.toFixed(1) + "% slower") + "\n");
|
||||
});
|
||||
}
|
||||
process.stdout.write("\n");
|
||||
});
|
||||
}
|
||||
|
||||
function getHz(bench) {
|
||||
return 1 / (bench.stats.mean + bench.stats.moe);
|
||||
}
|
||||
|
||||
function pad(str, len, l) {
|
||||
while (str.length < len)
|
||||
str = l ? str + " " : " " + str;
|
||||
return str;
|
||||
}
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
/**
|
||||
* Writes a 32 bit float to a buffer using little endian byte order.
|
||||
* @name writeFloatLE
|
||||
* @function
|
||||
* @param {number} val Value to write
|
||||
* @param {Uint8Array} buf Target buffer
|
||||
* @param {number} pos Target buffer offset
|
||||
* @returns {undefined}
|
||||
*/
|
||||
export function writeFloatLE(val: number, buf: Uint8Array, pos: number): void;
|
||||
|
||||
/**
|
||||
* Writes a 32 bit float to a buffer using big endian byte order.
|
||||
* @name writeFloatBE
|
||||
* @function
|
||||
* @param {number} val Value to write
|
||||
* @param {Uint8Array} buf Target buffer
|
||||
* @param {number} pos Target buffer offset
|
||||
* @returns {undefined}
|
||||
*/
|
||||
export function writeFloatBE(val: number, buf: Uint8Array, pos: number): void;
|
||||
|
||||
/**
|
||||
* Reads a 32 bit float from a buffer using little endian byte order.
|
||||
* @name readFloatLE
|
||||
* @function
|
||||
* @param {Uint8Array} buf Source buffer
|
||||
* @param {number} pos Source buffer offset
|
||||
* @returns {number} Value read
|
||||
*/
|
||||
export function readFloatLE(buf: Uint8Array, pos: number): number;
|
||||
|
||||
/**
|
||||
* Reads a 32 bit float from a buffer using big endian byte order.
|
||||
* @name readFloatBE
|
||||
* @function
|
||||
* @param {Uint8Array} buf Source buffer
|
||||
* @param {number} pos Source buffer offset
|
||||
* @returns {number} Value read
|
||||
*/
|
||||
export function readFloatBE(buf: Uint8Array, pos: number): number;
|
||||
|
||||
/**
|
||||
* Writes a 64 bit double to a buffer using little endian byte order.
|
||||
* @name writeDoubleLE
|
||||
* @function
|
||||
* @param {number} val Value to write
|
||||
* @param {Uint8Array} buf Target buffer
|
||||
* @param {number} pos Target buffer offset
|
||||
* @returns {undefined}
|
||||
*/
|
||||
export function writeDoubleLE(val: number, buf: Uint8Array, pos: number): void;
|
||||
|
||||
/**
|
||||
* Writes a 64 bit double to a buffer using big endian byte order.
|
||||
* @name writeDoubleBE
|
||||
* @function
|
||||
* @param {number} val Value to write
|
||||
* @param {Uint8Array} buf Target buffer
|
||||
* @param {number} pos Target buffer offset
|
||||
* @returns {undefined}
|
||||
*/
|
||||
export function writeDoubleBE(val: number, buf: Uint8Array, pos: number): void;
|
||||
|
||||
/**
|
||||
* Reads a 64 bit double from a buffer using little endian byte order.
|
||||
* @name readDoubleLE
|
||||
* @function
|
||||
* @param {Uint8Array} buf Source buffer
|
||||
* @param {number} pos Source buffer offset
|
||||
* @returns {number} Value read
|
||||
*/
|
||||
export function readDoubleLE(buf: Uint8Array, pos: number): number;
|
||||
|
||||
/**
|
||||
* Reads a 64 bit double from a buffer using big endian byte order.
|
||||
* @name readDoubleBE
|
||||
* @function
|
||||
* @param {Uint8Array} buf Source buffer
|
||||
* @param {number} pos Source buffer offset
|
||||
* @returns {number} Value read
|
||||
*/
|
||||
export function readDoubleBE(buf: Uint8Array, pos: number): number;
|
||||
|
|
@ -0,0 +1,335 @@
|
|||
"use strict";
|
||||
|
||||
module.exports = factory(factory);
|
||||
|
||||
/**
|
||||
* Reads / writes floats / doubles from / to buffers.
|
||||
* @name util.float
|
||||
* @namespace
|
||||
*/
|
||||
|
||||
/**
|
||||
* Writes a 32 bit float to a buffer using little endian byte order.
|
||||
* @name util.float.writeFloatLE
|
||||
* @function
|
||||
* @param {number} val Value to write
|
||||
* @param {Uint8Array} buf Target buffer
|
||||
* @param {number} pos Target buffer offset
|
||||
* @returns {undefined}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Writes a 32 bit float to a buffer using big endian byte order.
|
||||
* @name util.float.writeFloatBE
|
||||
* @function
|
||||
* @param {number} val Value to write
|
||||
* @param {Uint8Array} buf Target buffer
|
||||
* @param {number} pos Target buffer offset
|
||||
* @returns {undefined}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Reads a 32 bit float from a buffer using little endian byte order.
|
||||
* @name util.float.readFloatLE
|
||||
* @function
|
||||
* @param {Uint8Array} buf Source buffer
|
||||
* @param {number} pos Source buffer offset
|
||||
* @returns {number} Value read
|
||||
*/
|
||||
|
||||
/**
|
||||
* Reads a 32 bit float from a buffer using big endian byte order.
|
||||
* @name util.float.readFloatBE
|
||||
* @function
|
||||
* @param {Uint8Array} buf Source buffer
|
||||
* @param {number} pos Source buffer offset
|
||||
* @returns {number} Value read
|
||||
*/
|
||||
|
||||
/**
|
||||
* Writes a 64 bit double to a buffer using little endian byte order.
|
||||
* @name util.float.writeDoubleLE
|
||||
* @function
|
||||
* @param {number} val Value to write
|
||||
* @param {Uint8Array} buf Target buffer
|
||||
* @param {number} pos Target buffer offset
|
||||
* @returns {undefined}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Writes a 64 bit double to a buffer using big endian byte order.
|
||||
* @name util.float.writeDoubleBE
|
||||
* @function
|
||||
* @param {number} val Value to write
|
||||
* @param {Uint8Array} buf Target buffer
|
||||
* @param {number} pos Target buffer offset
|
||||
* @returns {undefined}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Reads a 64 bit double from a buffer using little endian byte order.
|
||||
* @name util.float.readDoubleLE
|
||||
* @function
|
||||
* @param {Uint8Array} buf Source buffer
|
||||
* @param {number} pos Source buffer offset
|
||||
* @returns {number} Value read
|
||||
*/
|
||||
|
||||
/**
|
||||
* Reads a 64 bit double from a buffer using big endian byte order.
|
||||
* @name util.float.readDoubleBE
|
||||
* @function
|
||||
* @param {Uint8Array} buf Source buffer
|
||||
* @param {number} pos Source buffer offset
|
||||
* @returns {number} Value read
|
||||
*/
|
||||
|
||||
// Factory function for the purpose of node-based testing in modified global environments
|
||||
function factory(exports) {
|
||||
|
||||
// float: typed array
|
||||
if (typeof Float32Array !== "undefined") (function() {
|
||||
|
||||
var f32 = new Float32Array([ -0 ]),
|
||||
f8b = new Uint8Array(f32.buffer),
|
||||
le = f8b[3] === 128;
|
||||
|
||||
function writeFloat_f32_cpy(val, buf, pos) {
|
||||
f32[0] = val;
|
||||
buf[pos ] = f8b[0];
|
||||
buf[pos + 1] = f8b[1];
|
||||
buf[pos + 2] = f8b[2];
|
||||
buf[pos + 3] = f8b[3];
|
||||
}
|
||||
|
||||
function writeFloat_f32_rev(val, buf, pos) {
|
||||
f32[0] = val;
|
||||
buf[pos ] = f8b[3];
|
||||
buf[pos + 1] = f8b[2];
|
||||
buf[pos + 2] = f8b[1];
|
||||
buf[pos + 3] = f8b[0];
|
||||
}
|
||||
|
||||
/* istanbul ignore next */
|
||||
exports.writeFloatLE = le ? writeFloat_f32_cpy : writeFloat_f32_rev;
|
||||
/* istanbul ignore next */
|
||||
exports.writeFloatBE = le ? writeFloat_f32_rev : writeFloat_f32_cpy;
|
||||
|
||||
function readFloat_f32_cpy(buf, pos) {
|
||||
f8b[0] = buf[pos ];
|
||||
f8b[1] = buf[pos + 1];
|
||||
f8b[2] = buf[pos + 2];
|
||||
f8b[3] = buf[pos + 3];
|
||||
return f32[0];
|
||||
}
|
||||
|
||||
function readFloat_f32_rev(buf, pos) {
|
||||
f8b[3] = buf[pos ];
|
||||
f8b[2] = buf[pos + 1];
|
||||
f8b[1] = buf[pos + 2];
|
||||
f8b[0] = buf[pos + 3];
|
||||
return f32[0];
|
||||
}
|
||||
|
||||
/* istanbul ignore next */
|
||||
exports.readFloatLE = le ? readFloat_f32_cpy : readFloat_f32_rev;
|
||||
/* istanbul ignore next */
|
||||
exports.readFloatBE = le ? readFloat_f32_rev : readFloat_f32_cpy;
|
||||
|
||||
// float: ieee754
|
||||
})(); else (function() {
|
||||
|
||||
function writeFloat_ieee754(writeUint, val, buf, pos) {
|
||||
var sign = val < 0 ? 1 : 0;
|
||||
if (sign)
|
||||
val = -val;
|
||||
if (val === 0)
|
||||
writeUint(1 / val > 0 ? /* positive */ 0 : /* negative 0 */ 2147483648, buf, pos);
|
||||
else if (isNaN(val))
|
||||
writeUint(2143289344, buf, pos);
|
||||
else if (val > 3.4028234663852886e+38) // +-Infinity
|
||||
writeUint((sign << 31 | 2139095040) >>> 0, buf, pos);
|
||||
else if (val < 1.1754943508222875e-38) // denormal
|
||||
writeUint((sign << 31 | Math.round(val / 1.401298464324817e-45)) >>> 0, buf, pos);
|
||||
else {
|
||||
var exponent = Math.floor(Math.log(val) / Math.LN2),
|
||||
mantissa = Math.round(val * Math.pow(2, -exponent) * 8388608) & 8388607;
|
||||
writeUint((sign << 31 | exponent + 127 << 23 | mantissa) >>> 0, buf, pos);
|
||||
}
|
||||
}
|
||||
|
||||
exports.writeFloatLE = writeFloat_ieee754.bind(null, writeUintLE);
|
||||
exports.writeFloatBE = writeFloat_ieee754.bind(null, writeUintBE);
|
||||
|
||||
function readFloat_ieee754(readUint, buf, pos) {
|
||||
var uint = readUint(buf, pos),
|
||||
sign = (uint >> 31) * 2 + 1,
|
||||
exponent = uint >>> 23 & 255,
|
||||
mantissa = uint & 8388607;
|
||||
return exponent === 255
|
||||
? mantissa
|
||||
? NaN
|
||||
: sign * Infinity
|
||||
: exponent === 0 // denormal
|
||||
? sign * 1.401298464324817e-45 * mantissa
|
||||
: sign * Math.pow(2, exponent - 150) * (mantissa + 8388608);
|
||||
}
|
||||
|
||||
exports.readFloatLE = readFloat_ieee754.bind(null, readUintLE);
|
||||
exports.readFloatBE = readFloat_ieee754.bind(null, readUintBE);
|
||||
|
||||
})();
|
||||
|
||||
// double: typed array
|
||||
if (typeof Float64Array !== "undefined") (function() {
|
||||
|
||||
var f64 = new Float64Array([-0]),
|
||||
f8b = new Uint8Array(f64.buffer),
|
||||
le = f8b[7] === 128;
|
||||
|
||||
function writeDouble_f64_cpy(val, buf, pos) {
|
||||
f64[0] = val;
|
||||
buf[pos ] = f8b[0];
|
||||
buf[pos + 1] = f8b[1];
|
||||
buf[pos + 2] = f8b[2];
|
||||
buf[pos + 3] = f8b[3];
|
||||
buf[pos + 4] = f8b[4];
|
||||
buf[pos + 5] = f8b[5];
|
||||
buf[pos + 6] = f8b[6];
|
||||
buf[pos + 7] = f8b[7];
|
||||
}
|
||||
|
||||
function writeDouble_f64_rev(val, buf, pos) {
|
||||
f64[0] = val;
|
||||
buf[pos ] = f8b[7];
|
||||
buf[pos + 1] = f8b[6];
|
||||
buf[pos + 2] = f8b[5];
|
||||
buf[pos + 3] = f8b[4];
|
||||
buf[pos + 4] = f8b[3];
|
||||
buf[pos + 5] = f8b[2];
|
||||
buf[pos + 6] = f8b[1];
|
||||
buf[pos + 7] = f8b[0];
|
||||
}
|
||||
|
||||
/* istanbul ignore next */
|
||||
exports.writeDoubleLE = le ? writeDouble_f64_cpy : writeDouble_f64_rev;
|
||||
/* istanbul ignore next */
|
||||
exports.writeDoubleBE = le ? writeDouble_f64_rev : writeDouble_f64_cpy;
|
||||
|
||||
function readDouble_f64_cpy(buf, pos) {
|
||||
f8b[0] = buf[pos ];
|
||||
f8b[1] = buf[pos + 1];
|
||||
f8b[2] = buf[pos + 2];
|
||||
f8b[3] = buf[pos + 3];
|
||||
f8b[4] = buf[pos + 4];
|
||||
f8b[5] = buf[pos + 5];
|
||||
f8b[6] = buf[pos + 6];
|
||||
f8b[7] = buf[pos + 7];
|
||||
return f64[0];
|
||||
}
|
||||
|
||||
function readDouble_f64_rev(buf, pos) {
|
||||
f8b[7] = buf[pos ];
|
||||
f8b[6] = buf[pos + 1];
|
||||
f8b[5] = buf[pos + 2];
|
||||
f8b[4] = buf[pos + 3];
|
||||
f8b[3] = buf[pos + 4];
|
||||
f8b[2] = buf[pos + 5];
|
||||
f8b[1] = buf[pos + 6];
|
||||
f8b[0] = buf[pos + 7];
|
||||
return f64[0];
|
||||
}
|
||||
|
||||
/* istanbul ignore next */
|
||||
exports.readDoubleLE = le ? readDouble_f64_cpy : readDouble_f64_rev;
|
||||
/* istanbul ignore next */
|
||||
exports.readDoubleBE = le ? readDouble_f64_rev : readDouble_f64_cpy;
|
||||
|
||||
// double: ieee754
|
||||
})(); else (function() {
|
||||
|
||||
function writeDouble_ieee754(writeUint, off0, off1, val, buf, pos) {
|
||||
var sign = val < 0 ? 1 : 0;
|
||||
if (sign)
|
||||
val = -val;
|
||||
if (val === 0) {
|
||||
writeUint(0, buf, pos + off0);
|
||||
writeUint(1 / val > 0 ? /* positive */ 0 : /* negative 0 */ 2147483648, buf, pos + off1);
|
||||
} else if (isNaN(val)) {
|
||||
writeUint(0, buf, pos + off0);
|
||||
writeUint(2146959360, buf, pos + off1);
|
||||
} else if (val > 1.7976931348623157e+308) { // +-Infinity
|
||||
writeUint(0, buf, pos + off0);
|
||||
writeUint((sign << 31 | 2146435072) >>> 0, buf, pos + off1);
|
||||
} else {
|
||||
var mantissa;
|
||||
if (val < 2.2250738585072014e-308) { // denormal
|
||||
mantissa = val / 5e-324;
|
||||
writeUint(mantissa >>> 0, buf, pos + off0);
|
||||
writeUint((sign << 31 | mantissa / 4294967296) >>> 0, buf, pos + off1);
|
||||
} else {
|
||||
var exponent = Math.floor(Math.log(val) / Math.LN2);
|
||||
if (exponent === 1024)
|
||||
exponent = 1023;
|
||||
mantissa = val * Math.pow(2, -exponent);
|
||||
writeUint(mantissa * 4503599627370496 >>> 0, buf, pos + off0);
|
||||
writeUint((sign << 31 | exponent + 1023 << 20 | mantissa * 1048576 & 1048575) >>> 0, buf, pos + off1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
exports.writeDoubleLE = writeDouble_ieee754.bind(null, writeUintLE, 0, 4);
|
||||
exports.writeDoubleBE = writeDouble_ieee754.bind(null, writeUintBE, 4, 0);
|
||||
|
||||
function readDouble_ieee754(readUint, off0, off1, buf, pos) {
|
||||
var lo = readUint(buf, pos + off0),
|
||||
hi = readUint(buf, pos + off1);
|
||||
var sign = (hi >> 31) * 2 + 1,
|
||||
exponent = hi >>> 20 & 2047,
|
||||
mantissa = 4294967296 * (hi & 1048575) + lo;
|
||||
return exponent === 2047
|
||||
? mantissa
|
||||
? NaN
|
||||
: sign * Infinity
|
||||
: exponent === 0 // denormal
|
||||
? sign * 5e-324 * mantissa
|
||||
: sign * Math.pow(2, exponent - 1075) * (mantissa + 4503599627370496);
|
||||
}
|
||||
|
||||
exports.readDoubleLE = readDouble_ieee754.bind(null, readUintLE, 0, 4);
|
||||
exports.readDoubleBE = readDouble_ieee754.bind(null, readUintBE, 4, 0);
|
||||
|
||||
})();
|
||||
|
||||
return exports;
|
||||
}
|
||||
|
||||
// uint helpers
|
||||
|
||||
function writeUintLE(val, buf, pos) {
|
||||
buf[pos ] = val & 255;
|
||||
buf[pos + 1] = val >>> 8 & 255;
|
||||
buf[pos + 2] = val >>> 16 & 255;
|
||||
buf[pos + 3] = val >>> 24;
|
||||
}
|
||||
|
||||
function writeUintBE(val, buf, pos) {
|
||||
buf[pos ] = val >>> 24;
|
||||
buf[pos + 1] = val >>> 16 & 255;
|
||||
buf[pos + 2] = val >>> 8 & 255;
|
||||
buf[pos + 3] = val & 255;
|
||||
}
|
||||
|
||||
function readUintLE(buf, pos) {
|
||||
return (buf[pos ]
|
||||
| buf[pos + 1] << 8
|
||||
| buf[pos + 2] << 16
|
||||
| buf[pos + 3] << 24) >>> 0;
|
||||
}
|
||||
|
||||
function readUintBE(buf, pos) {
|
||||
return (buf[pos ] << 24
|
||||
| buf[pos + 1] << 16
|
||||
| buf[pos + 2] << 8
|
||||
| buf[pos + 3]) >>> 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"name": "@protobufjs/float",
|
||||
"description": "Reads / writes floats / doubles from / to buffers in both modern and ancient browsers.",
|
||||
"version": "1.0.2",
|
||||
"author": "Daniel Wirtz <dcode+protobufjs@dcode.io>",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/dcodeIO/protobuf.js.git"
|
||||
},
|
||||
"dependencies": {},
|
||||
"license": "BSD-3-Clause",
|
||||
"main": "index.js",
|
||||
"types": "index.d.ts",
|
||||
"devDependencies": {
|
||||
"benchmark": "^2.1.4",
|
||||
"chalk": "^1.1.3",
|
||||
"ieee754": "^1.1.8",
|
||||
"istanbul": "^0.4.5",
|
||||
"tape": "^4.6.3"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "tape tests/*.js",
|
||||
"coverage": "istanbul cover node_modules/tape/bin/tape tests/*.js",
|
||||
"bench": "node bench"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,100 @@
|
|||
var tape = require("tape");
|
||||
|
||||
var float = require("..");
|
||||
|
||||
tape.test("float", function(test) {
|
||||
|
||||
// default
|
||||
test.test(test.name + " - typed array", function(test) {
|
||||
runTest(float, test);
|
||||
});
|
||||
|
||||
// ieee754
|
||||
test.test(test.name + " - fallback", function(test) {
|
||||
var F32 = global.Float32Array,
|
||||
F64 = global.Float64Array;
|
||||
delete global.Float32Array;
|
||||
delete global.Float64Array;
|
||||
runTest(float({}), test);
|
||||
global.Float32Array = F32;
|
||||
global.Float64Array = F64;
|
||||
});
|
||||
});
|
||||
|
||||
function runTest(float, test) {
|
||||
|
||||
var common = [
|
||||
0,
|
||||
-0,
|
||||
Infinity,
|
||||
-Infinity,
|
||||
0.125,
|
||||
1024.5,
|
||||
-4096.5,
|
||||
NaN
|
||||
];
|
||||
|
||||
test.test(test.name + " - using 32 bits", function(test) {
|
||||
common.concat([
|
||||
3.4028234663852886e+38,
|
||||
1.1754943508222875e-38,
|
||||
1.1754946310819804e-39
|
||||
])
|
||||
.forEach(function(value) {
|
||||
var strval = value === 0 && 1 / value < 0 ? "-0" : value.toString();
|
||||
test.ok(
|
||||
checkValue(value, 4, float.readFloatLE, float.writeFloatLE, Buffer.prototype.writeFloatLE),
|
||||
"should write and read back " + strval + " (32 bit LE)"
|
||||
);
|
||||
test.ok(
|
||||
checkValue(value, 4, float.readFloatBE, float.writeFloatBE, Buffer.prototype.writeFloatBE),
|
||||
"should write and read back " + strval + " (32 bit BE)"
|
||||
);
|
||||
});
|
||||
test.end();
|
||||
});
|
||||
|
||||
test.test(test.name + " - using 64 bits", function(test) {
|
||||
common.concat([
|
||||
1.7976931348623157e+308,
|
||||
2.2250738585072014e-308,
|
||||
2.2250738585072014e-309
|
||||
])
|
||||
.forEach(function(value) {
|
||||
var strval = value === 0 && 1 / value < 0 ? "-0" : value.toString();
|
||||
test.ok(
|
||||
checkValue(value, 8, float.readDoubleLE, float.writeDoubleLE, Buffer.prototype.writeDoubleLE),
|
||||
"should write and read back " + strval + " (64 bit LE)"
|
||||
);
|
||||
test.ok(
|
||||
checkValue(value, 8, float.readDoubleBE, float.writeDoubleBE, Buffer.prototype.writeDoubleBE),
|
||||
"should write and read back " + strval + " (64 bit BE)"
|
||||
);
|
||||
});
|
||||
test.end();
|
||||
});
|
||||
|
||||
test.end();
|
||||
}
|
||||
|
||||
function checkValue(value, size, read, write, write_comp) {
|
||||
var buffer = new Buffer(size);
|
||||
write(value, buffer, 0);
|
||||
var value_comp = read(buffer, 0);
|
||||
var strval = value === 0 && 1 / value < 0 ? "-0" : value.toString();
|
||||
if (value !== value) {
|
||||
if (value_comp === value_comp)
|
||||
return false;
|
||||
} else if (value_comp !== value)
|
||||
return false;
|
||||
|
||||
var buffer_comp = new Buffer(size);
|
||||
write_comp.call(buffer_comp, value, 0);
|
||||
for (var i = 0; i < size; ++i)
|
||||
if (buffer[i] !== buffer_comp[i]) {
|
||||
console.error(">", buffer, buffer_comp);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
npm-debug.*
|
||||
node_modules/
|
||||
coverage/
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
Copyright (c) 2016, Daniel Wirtz All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of its author, nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
@protobufjs/inquire
|
||||
===================
|
||||
[](https://www.npmjs.com/package/@protobufjs/inquire)
|
||||
|
||||
Requires a module only if available and hides the require call from bundlers.
|
||||
|
||||
API
|
||||
---
|
||||
|
||||
* **inquire(moduleName: `string`): `?Object`**<br />
|
||||
Requires a module only if available.
|
||||
|
||||
**License:** [BSD 3-Clause License](https://opensource.org/licenses/BSD-3-Clause)
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
export = inquire;
|
||||
|
||||
/**
|
||||
* Requires a module only if available.
|
||||
* @memberof util
|
||||
* @param {string} moduleName Module to require
|
||||
* @returns {?Object} Required module if available and not empty, otherwise `null`
|
||||
*/
|
||||
declare function inquire(moduleName: string): Object;
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
"use strict";
|
||||
module.exports = inquire;
|
||||
|
||||
/**
|
||||
* Requires a module only if available.
|
||||
* @memberof util
|
||||
* @param {string} moduleName Module to require
|
||||
* @returns {?Object} Required module if available and not empty, otherwise `null`
|
||||
*/
|
||||
function inquire(moduleName) {
|
||||
try {
|
||||
var mod = eval("quire".replace(/^/,"re"))(moduleName); // eslint-disable-line no-eval
|
||||
if (mod && (mod.length || Object.keys(mod).length))
|
||||
return mod;
|
||||
} catch (e) {} // eslint-disable-line no-empty
|
||||
return null;
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"name": "@protobufjs/inquire",
|
||||
"description": "Requires a module only if available and hides the require call from bundlers.",
|
||||
"version": "1.1.0",
|
||||
"author": "Daniel Wirtz <dcode+protobufjs@dcode.io>",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/dcodeIO/protobuf.js.git"
|
||||
},
|
||||
"license": "BSD-3-Clause",
|
||||
"main": "index.js",
|
||||
"types": "index.d.ts",
|
||||
"devDependencies": {
|
||||
"istanbul": "^0.4.5",
|
||||
"tape": "^4.6.3"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "tape tests/*.js",
|
||||
"coverage": "istanbul cover node_modules/tape/bin/tape tests/*.js"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
module.exports = [1];
|
||||
|
|
@ -0,0 +1 @@
|
|||
module.exports = [];
|
||||
|
|
@ -0,0 +1 @@
|
|||
module.exports = {};
|
||||
|
|
@ -0,0 +1 @@
|
|||
module.exports = { a: 1 };
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
var tape = require("tape");
|
||||
|
||||
var inquire = require("..");
|
||||
|
||||
tape.test("inquire", function(test) {
|
||||
|
||||
test.equal(inquire("buffer").Buffer, Buffer, "should be able to require \"buffer\"");
|
||||
|
||||
test.equal(inquire("%invalid"), null, "should not be able to require \"%invalid\"");
|
||||
|
||||
test.equal(inquire("./tests/data/emptyObject"), null, "should return null when requiring a module exporting an empty object");
|
||||
|
||||
test.equal(inquire("./tests/data/emptyArray"), null, "should return null when requiring a module exporting an empty array");
|
||||
|
||||
test.same(inquire("./tests/data/object"), { a: 1 }, "should return the object if a non-empty object");
|
||||
|
||||
test.same(inquire("./tests/data/array"), [ 1 ], "should return the module if a non-empty array");
|
||||
|
||||
test.end();
|
||||
});
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
Copyright (c) 2016, Daniel Wirtz All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of its author, nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
@protobufjs/path
|
||||
================
|
||||
[](https://www.npmjs.com/package/@protobufjs/path)
|
||||
|
||||
A minimal path module to resolve Unix, Windows and URL paths alike.
|
||||
|
||||
API
|
||||
---
|
||||
|
||||
* **path.isAbsolute(path: `string`): `boolean`**<br />
|
||||
Tests if the specified path is absolute.
|
||||
|
||||
* **path.normalize(path: `string`): `string`**<br />
|
||||
Normalizes the specified path.
|
||||
|
||||
* **path.resolve(originPath: `string`, includePath: `string`, [alreadyNormalized=false: `boolean`]): `string`**<br />
|
||||
Resolves the specified include path against the specified origin path.
|
||||
|
||||
**License:** [BSD 3-Clause License](https://opensource.org/licenses/BSD-3-Clause)
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
/**
|
||||
* Tests if the specified path is absolute.
|
||||
* @param {string} path Path to test
|
||||
* @returns {boolean} `true` if path is absolute
|
||||
*/
|
||||
export function isAbsolute(path: string): boolean;
|
||||
|
||||
/**
|
||||
* Normalizes the specified path.
|
||||
* @param {string} path Path to normalize
|
||||
* @returns {string} Normalized path
|
||||
*/
|
||||
export function normalize(path: string): string;
|
||||
|
||||
/**
|
||||
* Resolves the specified include path against the specified origin path.
|
||||
* @param {string} originPath Path to the origin file
|
||||
* @param {string} includePath Include path relative to origin path
|
||||
* @param {boolean} [alreadyNormalized=false] `true` if both paths are already known to be normalized
|
||||
* @returns {string} Path to the include file
|
||||
*/
|
||||
export function resolve(originPath: string, includePath: string, alreadyNormalized?: boolean): string;
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
"use strict";
|
||||
|
||||
/**
|
||||
* A minimal path module to resolve Unix, Windows and URL paths alike.
|
||||
* @memberof util
|
||||
* @namespace
|
||||
*/
|
||||
var path = exports;
|
||||
|
||||
var isAbsolute =
|
||||
/**
|
||||
* Tests if the specified path is absolute.
|
||||
* @param {string} path Path to test
|
||||
* @returns {boolean} `true` if path is absolute
|
||||
*/
|
||||
path.isAbsolute = function isAbsolute(path) {
|
||||
return /^(?:\/|\w+:)/.test(path);
|
||||
};
|
||||
|
||||
var normalize =
|
||||
/**
|
||||
* Normalizes the specified path.
|
||||
* @param {string} path Path to normalize
|
||||
* @returns {string} Normalized path
|
||||
*/
|
||||
path.normalize = function normalize(path) {
|
||||
path = path.replace(/\\/g, "/")
|
||||
.replace(/\/{2,}/g, "/");
|
||||
var parts = path.split("/"),
|
||||
absolute = isAbsolute(path),
|
||||
prefix = "";
|
||||
if (absolute)
|
||||
prefix = parts.shift() + "/";
|
||||
for (var i = 0; i < parts.length;) {
|
||||
if (parts[i] === "..") {
|
||||
if (i > 0 && parts[i - 1] !== "..")
|
||||
parts.splice(--i, 2);
|
||||
else if (absolute)
|
||||
parts.splice(i, 1);
|
||||
else
|
||||
++i;
|
||||
} else if (parts[i] === ".")
|
||||
parts.splice(i, 1);
|
||||
else
|
||||
++i;
|
||||
}
|
||||
return prefix + parts.join("/");
|
||||
};
|
||||
|
||||
/**
|
||||
* Resolves the specified include path against the specified origin path.
|
||||
* @param {string} originPath Path to the origin file
|
||||
* @param {string} includePath Include path relative to origin path
|
||||
* @param {boolean} [alreadyNormalized=false] `true` if both paths are already known to be normalized
|
||||
* @returns {string} Path to the include file
|
||||
*/
|
||||
path.resolve = function resolve(originPath, includePath, alreadyNormalized) {
|
||||
if (!alreadyNormalized)
|
||||
includePath = normalize(includePath);
|
||||
if (isAbsolute(includePath))
|
||||
return includePath;
|
||||
if (!alreadyNormalized)
|
||||
originPath = normalize(originPath);
|
||||
return (originPath = originPath.replace(/(?:\/|^)[^/]+$/, "")).length ? normalize(originPath + "/" + includePath) : includePath;
|
||||
};
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"name": "@protobufjs/path",
|
||||
"description": "A minimal path module to resolve Unix, Windows and URL paths alike.",
|
||||
"version": "1.1.2",
|
||||
"author": "Daniel Wirtz <dcode+protobufjs@dcode.io>",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/dcodeIO/protobuf.js.git"
|
||||
},
|
||||
"license": "BSD-3-Clause",
|
||||
"main": "index.js",
|
||||
"types": "index.d.ts",
|
||||
"devDependencies": {
|
||||
"istanbul": "^0.4.5",
|
||||
"tape": "^4.6.3"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "tape tests/*.js",
|
||||
"coverage": "istanbul cover node_modules/tape/bin/tape tests/*.js"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
var tape = require("tape");
|
||||
|
||||
var path = require("..");
|
||||
|
||||
tape.test("path", function(test) {
|
||||
|
||||
test.ok(path.isAbsolute("X:\\some\\path\\file.js"), "should identify absolute windows paths");
|
||||
test.ok(path.isAbsolute("/some/path/file.js"), "should identify absolute unix paths");
|
||||
|
||||
test.notOk(path.isAbsolute("some\\path\\file.js"), "should identify relative windows paths");
|
||||
test.notOk(path.isAbsolute("some/path/file.js"), "should identify relative unix paths");
|
||||
|
||||
var paths = [
|
||||
{
|
||||
actual: "X:\\some\\..\\.\\path\\\\file.js",
|
||||
normal: "X:/path/file.js",
|
||||
resolve: {
|
||||
origin: "X:/path/origin.js",
|
||||
expected: "X:/path/file.js"
|
||||
}
|
||||
}, {
|
||||
actual: "some\\..\\.\\path\\\\file.js",
|
||||
normal: "path/file.js",
|
||||
resolve: {
|
||||
origin: "X:/path/origin.js",
|
||||
expected: "X:/path/path/file.js"
|
||||
}
|
||||
}, {
|
||||
actual: "/some/.././path//file.js",
|
||||
normal: "/path/file.js",
|
||||
resolve: {
|
||||
origin: "/path/origin.js",
|
||||
expected: "/path/file.js"
|
||||
}
|
||||
}, {
|
||||
actual: "some/.././path//file.js",
|
||||
normal: "path/file.js",
|
||||
resolve: {
|
||||
origin: "",
|
||||
expected: "path/file.js"
|
||||
}
|
||||
}, {
|
||||
actual: ".././path//file.js",
|
||||
normal: "../path/file.js"
|
||||
}, {
|
||||
actual: "/.././path//file.js",
|
||||
normal: "/path/file.js"
|
||||
}
|
||||
];
|
||||
|
||||
paths.forEach(function(p) {
|
||||
test.equal(path.normalize(p.actual), p.normal, "should normalize " + p.actual);
|
||||
if (p.resolve) {
|
||||
test.equal(path.resolve(p.resolve.origin, p.actual), p.resolve.expected, "should resolve " + p.actual);
|
||||
test.equal(path.resolve(p.resolve.origin, p.normal, true), p.resolve.expected, "should resolve " + p.normal + " (already normalized)");
|
||||
}
|
||||
});
|
||||
|
||||
test.end();
|
||||
});
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
npm-debug.*
|
||||
node_modules/
|
||||
coverage/
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
Copyright (c) 2016, Daniel Wirtz All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of its author, nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
@protobufjs/pool
|
||||
================
|
||||
[](https://www.npmjs.com/package/@protobufjs/pool)
|
||||
|
||||
A general purpose buffer pool.
|
||||
|
||||
API
|
||||
---
|
||||
|
||||
* **pool(alloc: `function(size: number): Uint8Array`, slice: `function(this: Uint8Array, start: number, end: number): Uint8Array`, [size=8192: `number`]): `function(size: number): Uint8Array`**<br />
|
||||
Creates a pooled allocator.
|
||||
|
||||
**License:** [BSD 3-Clause License](https://opensource.org/licenses/BSD-3-Clause)
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
export = pool;
|
||||
|
||||
/**
|
||||
* An allocator as used by {@link util.pool}.
|
||||
* @typedef PoolAllocator
|
||||
* @type {function}
|
||||
* @param {number} size Buffer size
|
||||
* @returns {Uint8Array} Buffer
|
||||
*/
|
||||
type PoolAllocator = (size: number) => Uint8Array;
|
||||
|
||||
/**
|
||||
* A slicer as used by {@link util.pool}.
|
||||
* @typedef PoolSlicer
|
||||
* @type {function}
|
||||
* @param {number} start Start offset
|
||||
* @param {number} end End offset
|
||||
* @returns {Uint8Array} Buffer slice
|
||||
* @this {Uint8Array}
|
||||
*/
|
||||
type PoolSlicer = (this: Uint8Array, start: number, end: number) => Uint8Array;
|
||||
|
||||
/**
|
||||
* A general purpose buffer pool.
|
||||
* @memberof util
|
||||
* @function
|
||||
* @param {PoolAllocator} alloc Allocator
|
||||
* @param {PoolSlicer} slice Slicer
|
||||
* @param {number} [size=8192] Slab size
|
||||
* @returns {PoolAllocator} Pooled allocator
|
||||
*/
|
||||
declare function pool(alloc: PoolAllocator, slice: PoolSlicer, size?: number): PoolAllocator;
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
"use strict";
|
||||
module.exports = pool;
|
||||
|
||||
/**
|
||||
* An allocator as used by {@link util.pool}.
|
||||
* @typedef PoolAllocator
|
||||
* @type {function}
|
||||
* @param {number} size Buffer size
|
||||
* @returns {Uint8Array} Buffer
|
||||
*/
|
||||
|
||||
/**
|
||||
* A slicer as used by {@link util.pool}.
|
||||
* @typedef PoolSlicer
|
||||
* @type {function}
|
||||
* @param {number} start Start offset
|
||||
* @param {number} end End offset
|
||||
* @returns {Uint8Array} Buffer slice
|
||||
* @this {Uint8Array}
|
||||
*/
|
||||
|
||||
/**
|
||||
* A general purpose buffer pool.
|
||||
* @memberof util
|
||||
* @function
|
||||
* @param {PoolAllocator} alloc Allocator
|
||||
* @param {PoolSlicer} slice Slicer
|
||||
* @param {number} [size=8192] Slab size
|
||||
* @returns {PoolAllocator} Pooled allocator
|
||||
*/
|
||||
function pool(alloc, slice, size) {
|
||||
var SIZE = size || 8192;
|
||||
var MAX = SIZE >>> 1;
|
||||
var slab = null;
|
||||
var offset = SIZE;
|
||||
return function pool_alloc(size) {
|
||||
if (size < 1 || size > MAX)
|
||||
return alloc(size);
|
||||
if (offset + size > SIZE) {
|
||||
slab = alloc(SIZE);
|
||||
offset = 0;
|
||||
}
|
||||
var buf = slice.call(slab, offset, offset += size);
|
||||
if (offset & 7) // align to 32 bit
|
||||
offset = (offset | 7) + 1;
|
||||
return buf;
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"name": "@protobufjs/pool",
|
||||
"description": "A general purpose buffer pool.",
|
||||
"version": "1.1.0",
|
||||
"author": "Daniel Wirtz <dcode+protobufjs@dcode.io>",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/dcodeIO/protobuf.js.git"
|
||||
},
|
||||
"license": "BSD-3-Clause",
|
||||
"main": "index.js",
|
||||
"types": "index.d.ts",
|
||||
"devDependencies": {
|
||||
"istanbul": "^0.4.5",
|
||||
"tape": "^4.6.3"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "tape tests/*.js",
|
||||
"coverage": "istanbul cover node_modules/tape/bin/tape tests/*.js"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
var tape = require("tape");
|
||||
|
||||
var pool = require("..");
|
||||
|
||||
if (typeof Uint8Array !== "undefined")
|
||||
tape.test("pool", function(test) {
|
||||
|
||||
var alloc = pool(function(size) { return new Uint8Array(size); }, Uint8Array.prototype.subarray);
|
||||
|
||||
var buf1 = alloc(0);
|
||||
test.equal(buf1.length, 0, "should allocate a buffer of size 0");
|
||||
|
||||
var buf2 = alloc(1);
|
||||
test.equal(buf2.length, 1, "should allocate a buffer of size 1 (initializes slab)");
|
||||
|
||||
test.notEqual(buf2.buffer, buf1.buffer, "should not reference the same backing buffer if previous buffer had size 0");
|
||||
test.equal(buf2.byteOffset, 0, "should allocate at byteOffset 0 when using a new slab");
|
||||
|
||||
buf1 = alloc(1);
|
||||
test.equal(buf1.buffer, buf2.buffer, "should reference the same backing buffer when allocating a chunk fitting into the slab");
|
||||
test.equal(buf1.byteOffset, 8, "should align slices to 32 bit and this allocate at byteOffset 8");
|
||||
|
||||
var buf3 = alloc(4097);
|
||||
test.notEqual(buf3.buffer, buf2.buffer, "should not reference the same backing buffer when allocating a buffer larger than half the backing buffer's size");
|
||||
|
||||
buf2 = alloc(4096);
|
||||
test.equal(buf2.buffer, buf1.buffer, "should reference the same backing buffer when allocating a buffer smaller or equal than half the backing buffer's size");
|
||||
|
||||
buf1 = alloc(4096);
|
||||
test.notEqual(buf1.buffer, buf2.buffer, "should not reference the same backing buffer when the slab is exhausted (initializes new slab)");
|
||||
|
||||
test.end();
|
||||
});
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
npm-debug.*
|
||||
node_modules/
|
||||
coverage/
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
Copyright (c) 2016, Daniel Wirtz All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of its author, nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
@protobufjs/utf8
|
||||
================
|
||||
[](https://www.npmjs.com/package/@protobufjs/utf8)
|
||||
|
||||
A minimal UTF8 implementation for number arrays.
|
||||
|
||||
API
|
||||
---
|
||||
|
||||
* **utf8.length(string: `string`): `number`**<br />
|
||||
Calculates the UTF8 byte length of a string.
|
||||
|
||||
* **utf8.read(buffer: `Uint8Array`, start: `number`, end: `number`): `string`**<br />
|
||||
Reads UTF8 bytes as a string.
|
||||
|
||||
* **utf8.write(string: `string`, buffer: `Uint8Array`, offset: `number`): `number`**<br />
|
||||
Writes a string as UTF8 bytes.
|
||||
|
||||
|
||||
**License:** [BSD 3-Clause License](https://opensource.org/licenses/BSD-3-Clause)
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
/**
|
||||
* Calculates the UTF8 byte length of a string.
|
||||
* @param {string} string String
|
||||
* @returns {number} Byte length
|
||||
*/
|
||||
export function length(string: string): number;
|
||||
|
||||
/**
|
||||
* Reads UTF8 bytes as a string.
|
||||
* @param {Uint8Array} buffer Source buffer
|
||||
* @param {number} start Source start
|
||||
* @param {number} end Source end
|
||||
* @returns {string} String read
|
||||
*/
|
||||
export function read(buffer: Uint8Array, start: number, end: number): string;
|
||||
|
||||
/**
|
||||
* Writes a string as UTF8 bytes.
|
||||
* @param {string} string Source string
|
||||
* @param {Uint8Array} buffer Destination buffer
|
||||
* @param {number} offset Destination offset
|
||||
* @returns {number} Bytes written
|
||||
*/
|
||||
export function write(string: string, buffer: Uint8Array, offset: number): number;
|
||||
|
|
@ -0,0 +1,105 @@
|
|||
"use strict";
|
||||
|
||||
/**
|
||||
* A minimal UTF8 implementation for number arrays.
|
||||
* @memberof util
|
||||
* @namespace
|
||||
*/
|
||||
var utf8 = exports;
|
||||
|
||||
/**
|
||||
* Calculates the UTF8 byte length of a string.
|
||||
* @param {string} string String
|
||||
* @returns {number} Byte length
|
||||
*/
|
||||
utf8.length = function utf8_length(string) {
|
||||
var len = 0,
|
||||
c = 0;
|
||||
for (var i = 0; i < string.length; ++i) {
|
||||
c = string.charCodeAt(i);
|
||||
if (c < 128)
|
||||
len += 1;
|
||||
else if (c < 2048)
|
||||
len += 2;
|
||||
else if ((c & 0xFC00) === 0xD800 && (string.charCodeAt(i + 1) & 0xFC00) === 0xDC00) {
|
||||
++i;
|
||||
len += 4;
|
||||
} else
|
||||
len += 3;
|
||||
}
|
||||
return len;
|
||||
};
|
||||
|
||||
/**
|
||||
* Reads UTF8 bytes as a string.
|
||||
* @param {Uint8Array} buffer Source buffer
|
||||
* @param {number} start Source start
|
||||
* @param {number} end Source end
|
||||
* @returns {string} String read
|
||||
*/
|
||||
utf8.read = function utf8_read(buffer, start, end) {
|
||||
var len = end - start;
|
||||
if (len < 1)
|
||||
return "";
|
||||
var parts = null,
|
||||
chunk = [],
|
||||
i = 0, // char offset
|
||||
t; // temporary
|
||||
while (start < end) {
|
||||
t = buffer[start++];
|
||||
if (t < 128)
|
||||
chunk[i++] = t;
|
||||
else if (t > 191 && t < 224)
|
||||
chunk[i++] = (t & 31) << 6 | buffer[start++] & 63;
|
||||
else if (t > 239 && t < 365) {
|
||||
t = ((t & 7) << 18 | (buffer[start++] & 63) << 12 | (buffer[start++] & 63) << 6 | buffer[start++] & 63) - 0x10000;
|
||||
chunk[i++] = 0xD800 + (t >> 10);
|
||||
chunk[i++] = 0xDC00 + (t & 1023);
|
||||
} else
|
||||
chunk[i++] = (t & 15) << 12 | (buffer[start++] & 63) << 6 | buffer[start++] & 63;
|
||||
if (i > 8191) {
|
||||
(parts || (parts = [])).push(String.fromCharCode.apply(String, chunk));
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
if (parts) {
|
||||
if (i)
|
||||
parts.push(String.fromCharCode.apply(String, chunk.slice(0, i)));
|
||||
return parts.join("");
|
||||
}
|
||||
return String.fromCharCode.apply(String, chunk.slice(0, i));
|
||||
};
|
||||
|
||||
/**
|
||||
* Writes a string as UTF8 bytes.
|
||||
* @param {string} string Source string
|
||||
* @param {Uint8Array} buffer Destination buffer
|
||||
* @param {number} offset Destination offset
|
||||
* @returns {number} Bytes written
|
||||
*/
|
||||
utf8.write = function utf8_write(string, buffer, offset) {
|
||||
var start = offset,
|
||||
c1, // character 1
|
||||
c2; // character 2
|
||||
for (var i = 0; i < string.length; ++i) {
|
||||
c1 = string.charCodeAt(i);
|
||||
if (c1 < 128) {
|
||||
buffer[offset++] = c1;
|
||||
} else if (c1 < 2048) {
|
||||
buffer[offset++] = c1 >> 6 | 192;
|
||||
buffer[offset++] = c1 & 63 | 128;
|
||||
} else if ((c1 & 0xFC00) === 0xD800 && ((c2 = string.charCodeAt(i + 1)) & 0xFC00) === 0xDC00) {
|
||||
c1 = 0x10000 + ((c1 & 0x03FF) << 10) + (c2 & 0x03FF);
|
||||
++i;
|
||||
buffer[offset++] = c1 >> 18 | 240;
|
||||
buffer[offset++] = c1 >> 12 & 63 | 128;
|
||||
buffer[offset++] = c1 >> 6 & 63 | 128;
|
||||
buffer[offset++] = c1 & 63 | 128;
|
||||
} else {
|
||||
buffer[offset++] = c1 >> 12 | 224;
|
||||
buffer[offset++] = c1 >> 6 & 63 | 128;
|
||||
buffer[offset++] = c1 & 63 | 128;
|
||||
}
|
||||
}
|
||||
return offset - start;
|
||||
};
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"name": "@protobufjs/utf8",
|
||||
"description": "A minimal UTF8 implementation for number arrays.",
|
||||
"version": "1.1.0",
|
||||
"author": "Daniel Wirtz <dcode+protobufjs@dcode.io>",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/dcodeIO/protobuf.js.git"
|
||||
},
|
||||
"license": "BSD-3-Clause",
|
||||
"main": "index.js",
|
||||
"types": "index.d.ts",
|
||||
"devDependencies": {
|
||||
"istanbul": "^0.4.5",
|
||||
"tape": "^4.6.3"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "tape tests/*.js",
|
||||
"coverage": "istanbul cover node_modules/tape/bin/tape tests/*.js"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,216 @@
|
|||
UTF-8 encoded sample plain-text file
|
||||
‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
|
||||
Markus Kuhn [ˈmaʳkʊs kuːn] <http://www.cl.cam.ac.uk/~mgk25/> — 2002-07-25 CC BY
|
||||
|
||||
|
||||
The ASCII compatible UTF-8 encoding used in this plain-text file
|
||||
is defined in Unicode, ISO 10646-1, and RFC 2279.
|
||||
|
||||
|
||||
Using Unicode/UTF-8, you can write in emails and source code things such as
|
||||
|
||||
Mathematics and sciences:
|
||||
|
||||
∮ E⋅da = Q, n → ∞, ∑ f(i) = ∏ g(i), ⎧⎡⎛┌─────┐⎞⎤⎫
|
||||
⎪⎢⎜│a²+b³ ⎟⎥⎪
|
||||
∀x∈ℝ: ⌈x⌉ = −⌊−x⌋, α ∧ ¬β = ¬(¬α ∨ β), ⎪⎢⎜│───── ⎟⎥⎪
|
||||
⎪⎢⎜⎷ c₈ ⎟⎥⎪
|
||||
ℕ ⊆ ℕ₀ ⊂ ℤ ⊂ ℚ ⊂ ℝ ⊂ ℂ, ⎨⎢⎜ ⎟⎥⎬
|
||||
⎪⎢⎜ ∞ ⎟⎥⎪
|
||||
⊥ < a ≠ b ≡ c ≤ d ≪ ⊤ ⇒ (⟦A⟧ ⇔ ⟪B⟫), ⎪⎢⎜ ⎲ ⎟⎥⎪
|
||||
⎪⎢⎜ ⎳aⁱ-bⁱ⎟⎥⎪
|
||||
2H₂ + O₂ ⇌ 2H₂O, R = 4.7 kΩ, ⌀ 200 mm ⎩⎣⎝i=1 ⎠⎦⎭
|
||||
|
||||
Linguistics and dictionaries:
|
||||
|
||||
ði ıntəˈnæʃənəl fəˈnɛtık əsoʊsiˈeıʃn
|
||||
Y [ˈʏpsilɔn], Yen [jɛn], Yoga [ˈjoːgɑ]
|
||||
|
||||
APL:
|
||||
|
||||
((V⍳V)=⍳⍴V)/V←,V ⌷←⍳→⍴∆∇⊃‾⍎⍕⌈
|
||||
|
||||
Nicer typography in plain text files:
|
||||
|
||||
╔══════════════════════════════════════════╗
|
||||
║ ║
|
||||
║ • ‘single’ and “double” quotes ║
|
||||
║ ║
|
||||
║ • Curly apostrophes: “We’ve been here” ║
|
||||
║ ║
|
||||
║ • Latin-1 apostrophe and accents: '´` ║
|
||||
║ ║
|
||||
║ • ‚deutsche‘ „Anführungszeichen“ ║
|
||||
║ ║
|
||||
║ • †, ‡, ‰, •, 3–4, —, −5/+5, ™, … ║
|
||||
║ ║
|
||||
║ • ASCII safety test: 1lI|, 0OD, 8B ║
|
||||
║ ╭─────────╮ ║
|
||||
║ • the euro symbol: │ 14.95 € │ ║
|
||||
║ ╰─────────╯ ║
|
||||
╚══════════════════════════════════════════╝
|
||||
|
||||
Combining characters:
|
||||
|
||||
STARGΛ̊TE SG-1, a = v̇ = r̈, a⃑ ⊥ b⃑
|
||||
|
||||
Greek (in Polytonic):
|
||||
|
||||
The Greek anthem:
|
||||
|
||||
Σὲ γνωρίζω ἀπὸ τὴν κόψη
|
||||
τοῦ σπαθιοῦ τὴν τρομερή,
|
||||
σὲ γνωρίζω ἀπὸ τὴν ὄψη
|
||||
ποὺ μὲ βία μετράει τὴ γῆ.
|
||||
|
||||
᾿Απ᾿ τὰ κόκκαλα βγαλμένη
|
||||
τῶν ῾Ελλήνων τὰ ἱερά
|
||||
καὶ σὰν πρῶτα ἀνδρειωμένη
|
||||
χαῖρε, ὦ χαῖρε, ᾿Ελευθεριά!
|
||||
|
||||
From a speech of Demosthenes in the 4th century BC:
|
||||
|
||||
Οὐχὶ ταὐτὰ παρίσταταί μοι γιγνώσκειν, ὦ ἄνδρες ᾿Αθηναῖοι,
|
||||
ὅταν τ᾿ εἰς τὰ πράγματα ἀποβλέψω καὶ ὅταν πρὸς τοὺς
|
||||
λόγους οὓς ἀκούω· τοὺς μὲν γὰρ λόγους περὶ τοῦ
|
||||
τιμωρήσασθαι Φίλιππον ὁρῶ γιγνομένους, τὰ δὲ πράγματ᾿
|
||||
εἰς τοῦτο προήκοντα, ὥσθ᾿ ὅπως μὴ πεισόμεθ᾿ αὐτοὶ
|
||||
πρότερον κακῶς σκέψασθαι δέον. οὐδέν οὖν ἄλλο μοι δοκοῦσιν
|
||||
οἱ τὰ τοιαῦτα λέγοντες ἢ τὴν ὑπόθεσιν, περὶ ἧς βουλεύεσθαι,
|
||||
οὐχὶ τὴν οὖσαν παριστάντες ὑμῖν ἁμαρτάνειν. ἐγὼ δέ, ὅτι μέν
|
||||
ποτ᾿ ἐξῆν τῇ πόλει καὶ τὰ αὑτῆς ἔχειν ἀσφαλῶς καὶ Φίλιππον
|
||||
τιμωρήσασθαι, καὶ μάλ᾿ ἀκριβῶς οἶδα· ἐπ᾿ ἐμοῦ γάρ, οὐ πάλαι
|
||||
γέγονεν ταῦτ᾿ ἀμφότερα· νῦν μέντοι πέπεισμαι τοῦθ᾿ ἱκανὸν
|
||||
προλαβεῖν ἡμῖν εἶναι τὴν πρώτην, ὅπως τοὺς συμμάχους
|
||||
σώσομεν. ἐὰν γὰρ τοῦτο βεβαίως ὑπάρξῃ, τότε καὶ περὶ τοῦ
|
||||
τίνα τιμωρήσεταί τις καὶ ὃν τρόπον ἐξέσται σκοπεῖν· πρὶν δὲ
|
||||
τὴν ἀρχὴν ὀρθῶς ὑποθέσθαι, μάταιον ἡγοῦμαι περὶ τῆς
|
||||
τελευτῆς ὁντινοῦν ποιεῖσθαι λόγον.
|
||||
|
||||
Δημοσθένους, Γ´ ᾿Ολυνθιακὸς
|
||||
|
||||
Georgian:
|
||||
|
||||
From a Unicode conference invitation:
|
||||
|
||||
გთხოვთ ახლავე გაიაროთ რეგისტრაცია Unicode-ის მეათე საერთაშორისო
|
||||
კონფერენციაზე დასასწრებად, რომელიც გაიმართება 10-12 მარტს,
|
||||
ქ. მაინცში, გერმანიაში. კონფერენცია შეჰკრებს ერთად მსოფლიოს
|
||||
ექსპერტებს ისეთ დარგებში როგორიცაა ინტერნეტი და Unicode-ი,
|
||||
ინტერნაციონალიზაცია და ლოკალიზაცია, Unicode-ის გამოყენება
|
||||
ოპერაციულ სისტემებსა, და გამოყენებით პროგრამებში, შრიფტებში,
|
||||
ტექსტების დამუშავებასა და მრავალენოვან კომპიუტერულ სისტემებში.
|
||||
|
||||
Russian:
|
||||
|
||||
From a Unicode conference invitation:
|
||||
|
||||
Зарегистрируйтесь сейчас на Десятую Международную Конференцию по
|
||||
Unicode, которая состоится 10-12 марта 1997 года в Майнце в Германии.
|
||||
Конференция соберет широкий круг экспертов по вопросам глобального
|
||||
Интернета и Unicode, локализации и интернационализации, воплощению и
|
||||
применению Unicode в различных операционных системах и программных
|
||||
приложениях, шрифтах, верстке и многоязычных компьютерных системах.
|
||||
|
||||
Thai (UCS Level 2):
|
||||
|
||||
Excerpt from a poetry on The Romance of The Three Kingdoms (a Chinese
|
||||
classic 'San Gua'):
|
||||
|
||||
[----------------------------|------------------------]
|
||||
๏ แผ่นดินฮั่นเสื่อมโทรมแสนสังเวช พระปกเกศกองบู๊กู้ขึ้นใหม่
|
||||
สิบสองกษัตริย์ก่อนหน้าแลถัดไป สององค์ไซร้โง่เขลาเบาปัญญา
|
||||
ทรงนับถือขันทีเป็นที่พึ่ง บ้านเมืองจึงวิปริตเป็นนักหนา
|
||||
โฮจิ๋นเรียกทัพทั่วหัวเมืองมา หมายจะฆ่ามดชั่วตัวสำคัญ
|
||||
เหมือนขับไสไล่เสือจากเคหา รับหมาป่าเข้ามาเลยอาสัญ
|
||||
ฝ่ายอ้องอุ้นยุแยกให้แตกกัน ใช้สาวนั้นเป็นชนวนชื่นชวนใจ
|
||||
พลันลิฉุยกุยกีกลับก่อเหตุ ช่างอาเพศจริงหนาฟ้าร้องไห้
|
||||
ต้องรบราฆ่าฟันจนบรรลัย ฤๅหาใครค้ำชูกู้บรรลังก์ ฯ
|
||||
|
||||
(The above is a two-column text. If combining characters are handled
|
||||
correctly, the lines of the second column should be aligned with the
|
||||
| character above.)
|
||||
|
||||
Ethiopian:
|
||||
|
||||
Proverbs in the Amharic language:
|
||||
|
||||
ሰማይ አይታረስ ንጉሥ አይከሰስ።
|
||||
ብላ ካለኝ እንደአባቴ በቆመጠኝ።
|
||||
ጌጥ ያለቤቱ ቁምጥና ነው።
|
||||
ደሀ በሕልሙ ቅቤ ባይጠጣ ንጣት በገደለው።
|
||||
የአፍ ወለምታ በቅቤ አይታሽም።
|
||||
አይጥ በበላ ዳዋ ተመታ።
|
||||
ሲተረጉሙ ይደረግሙ።
|
||||
ቀስ በቀስ፥ ዕንቁላል በእግሩ ይሄዳል።
|
||||
ድር ቢያብር አንበሳ ያስር።
|
||||
ሰው እንደቤቱ እንጅ እንደ ጉረቤቱ አይተዳደርም።
|
||||
እግዜር የከፈተውን ጉሮሮ ሳይዘጋው አይድርም።
|
||||
የጎረቤት ሌባ፥ ቢያዩት ይስቅ ባያዩት ያጠልቅ።
|
||||
ሥራ ከመፍታት ልጄን ላፋታት።
|
||||
ዓባይ ማደሪያ የለው፥ ግንድ ይዞ ይዞራል።
|
||||
የእስላም አገሩ መካ የአሞራ አገሩ ዋርካ።
|
||||
ተንጋሎ ቢተፉ ተመልሶ ባፉ።
|
||||
ወዳጅህ ማር ቢሆን ጨርስህ አትላሰው።
|
||||
እግርህን በፍራሽህ ልክ ዘርጋ።
|
||||
|
||||
Runes:
|
||||
|
||||
ᚻᛖ ᚳᚹᚫᚦ ᚦᚫᛏ ᚻᛖ ᛒᚢᛞᛖ ᚩᚾ ᚦᚫᛗ ᛚᚪᚾᛞᛖ ᚾᚩᚱᚦᚹᛖᚪᚱᛞᚢᛗ ᚹᛁᚦ ᚦᚪ ᚹᛖᛥᚫ
|
||||
|
||||
(Old English, which transcribed into Latin reads 'He cwaeth that he
|
||||
bude thaem lande northweardum with tha Westsae.' and means 'He said
|
||||
that he lived in the northern land near the Western Sea.')
|
||||
|
||||
Braille:
|
||||
|
||||
⡌⠁⠧⠑ ⠼⠁⠒ ⡍⠜⠇⠑⠹⠰⠎ ⡣⠕⠌
|
||||
|
||||
⡍⠜⠇⠑⠹ ⠺⠁⠎ ⠙⠑⠁⠙⠒ ⠞⠕ ⠃⠑⠛⠔ ⠺⠊⠹⠲ ⡹⠻⠑ ⠊⠎ ⠝⠕ ⠙⠳⠃⠞
|
||||
⠱⠁⠞⠑⠧⠻ ⠁⠃⠳⠞ ⠹⠁⠞⠲ ⡹⠑ ⠗⠑⠛⠊⠌⠻ ⠕⠋ ⠙⠊⠎ ⠃⠥⠗⠊⠁⠇ ⠺⠁⠎
|
||||
⠎⠊⠛⠝⠫ ⠃⠹ ⠹⠑ ⠊⠇⠻⠛⠹⠍⠁⠝⠂ ⠹⠑ ⠊⠇⠻⠅⠂ ⠹⠑ ⠥⠝⠙⠻⠞⠁⠅⠻⠂
|
||||
⠁⠝⠙ ⠹⠑ ⠡⠊⠑⠋ ⠍⠳⠗⠝⠻⠲ ⡎⠊⠗⠕⠕⠛⠑ ⠎⠊⠛⠝⠫ ⠊⠞⠲ ⡁⠝⠙
|
||||
⡎⠊⠗⠕⠕⠛⠑⠰⠎ ⠝⠁⠍⠑ ⠺⠁⠎ ⠛⠕⠕⠙ ⠥⠏⠕⠝ ⠰⡡⠁⠝⠛⠑⠂ ⠋⠕⠗ ⠁⠝⠹⠹⠔⠛ ⠙⠑
|
||||
⠡⠕⠎⠑ ⠞⠕ ⠏⠥⠞ ⠙⠊⠎ ⠙⠁⠝⠙ ⠞⠕⠲
|
||||
|
||||
⡕⠇⠙ ⡍⠜⠇⠑⠹ ⠺⠁⠎ ⠁⠎ ⠙⠑⠁⠙ ⠁⠎ ⠁ ⠙⠕⠕⠗⠤⠝⠁⠊⠇⠲
|
||||
|
||||
⡍⠔⠙⠖ ⡊ ⠙⠕⠝⠰⠞ ⠍⠑⠁⠝ ⠞⠕ ⠎⠁⠹ ⠹⠁⠞ ⡊ ⠅⠝⠪⠂ ⠕⠋ ⠍⠹
|
||||
⠪⠝ ⠅⠝⠪⠇⠫⠛⠑⠂ ⠱⠁⠞ ⠹⠻⠑ ⠊⠎ ⠏⠜⠞⠊⠊⠥⠇⠜⠇⠹ ⠙⠑⠁⠙ ⠁⠃⠳⠞
|
||||
⠁ ⠙⠕⠕⠗⠤⠝⠁⠊⠇⠲ ⡊ ⠍⠊⠣⠞ ⠙⠁⠧⠑ ⠃⠑⠲ ⠔⠊⠇⠔⠫⠂ ⠍⠹⠎⠑⠇⠋⠂ ⠞⠕
|
||||
⠗⠑⠛⠜⠙ ⠁ ⠊⠕⠋⠋⠔⠤⠝⠁⠊⠇ ⠁⠎ ⠹⠑ ⠙⠑⠁⠙⠑⠌ ⠏⠊⠑⠊⠑ ⠕⠋ ⠊⠗⠕⠝⠍⠕⠝⠛⠻⠹
|
||||
⠔ ⠹⠑ ⠞⠗⠁⠙⠑⠲ ⡃⠥⠞ ⠹⠑ ⠺⠊⠎⠙⠕⠍ ⠕⠋ ⠳⠗ ⠁⠝⠊⠑⠌⠕⠗⠎
|
||||
⠊⠎ ⠔ ⠹⠑ ⠎⠊⠍⠊⠇⠑⠆ ⠁⠝⠙ ⠍⠹ ⠥⠝⠙⠁⠇⠇⠪⠫ ⠙⠁⠝⠙⠎
|
||||
⠩⠁⠇⠇ ⠝⠕⠞ ⠙⠊⠌⠥⠗⠃ ⠊⠞⠂ ⠕⠗ ⠹⠑ ⡊⠳⠝⠞⠗⠹⠰⠎ ⠙⠕⠝⠑ ⠋⠕⠗⠲ ⡹⠳
|
||||
⠺⠊⠇⠇ ⠹⠻⠑⠋⠕⠗⠑ ⠏⠻⠍⠊⠞ ⠍⠑ ⠞⠕ ⠗⠑⠏⠑⠁⠞⠂ ⠑⠍⠏⠙⠁⠞⠊⠊⠁⠇⠇⠹⠂ ⠹⠁⠞
|
||||
⡍⠜⠇⠑⠹ ⠺⠁⠎ ⠁⠎ ⠙⠑⠁⠙ ⠁⠎ ⠁ ⠙⠕⠕⠗⠤⠝⠁⠊⠇⠲
|
||||
|
||||
(The first couple of paragraphs of "A Christmas Carol" by Dickens)
|
||||
|
||||
Compact font selection example text:
|
||||
|
||||
ABCDEFGHIJKLMNOPQRSTUVWXYZ /0123456789
|
||||
abcdefghijklmnopqrstuvwxyz £©µÀÆÖÞßéöÿ
|
||||
–—‘“”„†•…‰™œŠŸž€ ΑΒΓΔΩαβγδω АБВГДабвгд
|
||||
∀∂∈ℝ∧∪≡∞ ↑↗↨↻⇣ ┐┼╔╘░►☺♀ fi<>⑀₂ἠḂӥẄɐː⍎אԱა
|
||||
|
||||
Greetings in various languages:
|
||||
|
||||
Hello world, Καλημέρα κόσμε, コンニチハ
|
||||
|
||||
Box drawing alignment tests: █
|
||||
▉
|
||||
╔══╦══╗ ┌──┬──┐ ╭──┬──╮ ╭──┬──╮ ┏━━┳━━┓ ┎┒┏┑ ╷ ╻ ┏┯┓ ┌┰┐ ▊ ╱╲╱╲╳╳╳
|
||||
║┌─╨─┐║ │╔═╧═╗│ │╒═╪═╕│ │╓─╁─╖│ ┃┌─╂─┐┃ ┗╃╄┙ ╶┼╴╺╋╸┠┼┨ ┝╋┥ ▋ ╲╱╲╱╳╳╳
|
||||
║│╲ ╱│║ │║ ║│ ││ │ ││ │║ ┃ ║│ ┃│ ╿ │┃ ┍╅╆┓ ╵ ╹ ┗┷┛ └┸┘ ▌ ╱╲╱╲╳╳╳
|
||||
╠╡ ╳ ╞╣ ├╢ ╟┤ ├┼─┼─┼┤ ├╫─╂─╫┤ ┣┿╾┼╼┿┫ ┕┛┖┚ ┌┄┄┐ ╎ ┏┅┅┓ ┋ ▍ ╲╱╲╱╳╳╳
|
||||
║│╱ ╲│║ │║ ║│ ││ │ ││ │║ ┃ ║│ ┃│ ╽ │┃ ░░▒▒▓▓██ ┊ ┆ ╎ ╏ ┇ ┋ ▎
|
||||
║└─╥─┘║ │╚═╤═╝│ │╘═╪═╛│ │╙─╀─╜│ ┃└─╂─┘┃ ░░▒▒▓▓██ ┊ ┆ ╎ ╏ ┇ ┋ ▏
|
||||
╚══╩══╝ └──┴──┘ ╰──┴──╯ ╰──┴──╯ ┗━━┻━━┛ ▗▄▖▛▀▜ └╌╌┘ ╎ ┗╍╍┛ ┋ ▁▂▃▄▅▆▇█
|
||||
▝▀▘▙▄▟
|
||||
|
||||
Surrogates:
|
||||
|
||||
𠜎 𠜱 𠝹 𠱓 𠱸 𠲖 𠳏 𠳕 𠴕 𠵼 𠵿 𠸎 𠸏 𠹷 𠺝 𠺢 𠻗 𠻹 𠻺 𠼭 𠼮 𠽌 𠾴 𠾼 𠿪 𡁜 𡁯 𡁵 𡁶 𡁻 𡃁
|
||||
𡃉 𡇙 𢃇 𢞵 𢫕 𢭃 𢯊 𢱑 𢱕 𢳂 𢴈 𢵌 𢵧 𢺳 𣲷 𤓓 𤶸 𤷪 𥄫 𦉘 𦟌 𦧲 𦧺 𧨾 𨅝 𨈇 𨋢 𨳊 𨳍 𨳒 𩶘
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
var tape = require("tape");
|
||||
|
||||
var utf8 = require("..");
|
||||
|
||||
var data = require("fs").readFileSync(require.resolve("./data/utf8.txt")),
|
||||
dataStr = data.toString("utf8");
|
||||
|
||||
tape.test("utf8", function(test) {
|
||||
|
||||
test.test(test.name + " - length", function(test) {
|
||||
test.equal(utf8.length(""), 0, "should return a byte length of zero for an empty string");
|
||||
|
||||
test.equal(utf8.length(dataStr), Buffer.byteLength(dataStr), "should return the same byte length as node buffers");
|
||||
|
||||
test.end();
|
||||
});
|
||||
|
||||
test.test(test.name + " - read", function(test) {
|
||||
var comp = utf8.read([], 0, 0);
|
||||
test.equal(comp, "", "should decode an empty buffer to an empty string");
|
||||
|
||||
comp = utf8.read(data, 0, data.length);
|
||||
test.equal(comp, data.toString("utf8"), "should decode to the same byte data as node buffers");
|
||||
|
||||
var longData = Buffer.concat([data, data, data, data]);
|
||||
comp = utf8.read(longData, 0, longData.length);
|
||||
test.equal(comp, longData.toString("utf8"), "should decode to the same byte data as node buffers (long)");
|
||||
|
||||
var chunkData = new Buffer(data.toString("utf8").substring(0, 8192));
|
||||
comp = utf8.read(chunkData, 0, chunkData.length);
|
||||
test.equal(comp, chunkData.toString("utf8"), "should decode to the same byte data as node buffers (chunk size)");
|
||||
|
||||
test.end();
|
||||
});
|
||||
|
||||
test.test(test.name + " - write", function(test) {
|
||||
var buf = new Buffer(0);
|
||||
test.equal(utf8.write("", buf, 0), 0, "should encode an empty string to an empty buffer");
|
||||
|
||||
var len = utf8.length(dataStr);
|
||||
buf = new Buffer(len);
|
||||
test.equal(utf8.write(dataStr, buf, 0), len, "should encode to exactly " + len + " bytes");
|
||||
|
||||
test.equal(buf.length, data.length, "should encode to a buffer length equal to that of node buffers");
|
||||
|
||||
for (var i = 0; i < buf.length; ++i) {
|
||||
if (buf[i] !== data[i]) {
|
||||
test.fail("should encode to the same buffer data as node buffers (offset " + i + ")");
|
||||
return;
|
||||
}
|
||||
}
|
||||
test.pass("should encode to the same buffer data as node buffers");
|
||||
|
||||
test.end();
|
||||
});
|
||||
|
||||
});
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) Microsoft Corporation.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
# Installation
|
||||
> `npm install --save @types/node`
|
||||
|
||||
# Summary
|
||||
This package contains type definitions for node (https://nodejs.org/).
|
||||
|
||||
# Details
|
||||
Files were exported from https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/node.
|
||||
|
||||
### Additional Details
|
||||
* Last updated: Tue, 14 May 2024 06:09:35 GMT
|
||||
* Dependencies: [undici-types](https://npmjs.com/package/undici-types)
|
||||
|
||||
# Credits
|
||||
These definitions were written by [Microsoft TypeScript](https://github.com/Microsoft), [Alberto Schiabel](https://github.com/jkomyno), [Alvis HT Tang](https://github.com/alvis), [Andrew Makarov](https://github.com/r3nya), [Benjamin Toueg](https://github.com/btoueg), [Chigozirim C.](https://github.com/smac89), [David Junger](https://github.com/touffy), [Deividas Bakanas](https://github.com/DeividasBakanas), [Eugene Y. Q. Shen](https://github.com/eyqs), [Hannes Magnusson](https://github.com/Hannes-Magnusson-CK), [Huw](https://github.com/hoo29), [Kelvin Jin](https://github.com/kjin), [Klaus Meinhardt](https://github.com/ajafff), [Lishude](https://github.com/islishude), [Mariusz Wiktorczyk](https://github.com/mwiktorczyk), [Mohsen Azimi](https://github.com/mohsen1), [Nikita Galkin](https://github.com/galkin), [Parambir Singh](https://github.com/parambirs), [Sebastian Silbermann](https://github.com/eps1lon), [Thomas den Hollander](https://github.com/ThomasdenH), [Wilco Bakker](https://github.com/WilcoBakker), [wwwy3y3](https://github.com/wwwy3y3), [Samuel Ainsworth](https://github.com/samuela), [Kyle Uehlein](https://github.com/kuehlein), [Thanik Bhongbhibhat](https://github.com/bhongy), [Marcin Kopacz](https://github.com/chyzwar), [Trivikram Kamat](https://github.com/trivikr), [Junxiao Shi](https://github.com/yoursunny), [Ilia Baryshnikov](https://github.com/qwelias), [ExE Boss](https://github.com/ExE-Boss), [Piotr Błażejewicz](https://github.com/peterblazejewicz), [Anna Henningsen](https://github.com/addaleax), [Victor Perin](https://github.com/victorperin), [Yongsheng Zhang](https://github.com/ZYSzys), [NodeJS Contributors](https://github.com/NodeJS), [Linus Unnebäck](https://github.com/LinusU), [wafuwafu13](https://github.com/wafuwafu13), [Matteo Collina](https://github.com/mcollina), and [Dmitry Semigradsky](https://github.com/Semigradsky).
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,8 @@
|
|||
declare module "assert/strict" {
|
||||
import { strict } from "node:assert";
|
||||
export = strict;
|
||||
}
|
||||
declare module "node:assert/strict" {
|
||||
import { strict } from "node:assert";
|
||||
export = strict;
|
||||
}
|
||||
|
|
@ -0,0 +1,541 @@
|
|||
/**
|
||||
* We strongly discourage the use of the `async_hooks` API.
|
||||
* Other APIs that can cover most of its use cases include:
|
||||
*
|
||||
* * [`AsyncLocalStorage`](https://nodejs.org/docs/latest-v20.x/api/async_context.html#class-asynclocalstorage) tracks async context
|
||||
* * [`process.getActiveResourcesInfo()`](https://nodejs.org/docs/latest-v20.x/api/process.html#processgetactiveresourcesinfo) tracks active resources
|
||||
*
|
||||
* The `node:async_hooks` module provides an API to track asynchronous resources.
|
||||
* It can be accessed using:
|
||||
*
|
||||
* ```js
|
||||
* import async_hooks from 'node:async_hooks';
|
||||
* ```
|
||||
* @experimental
|
||||
* @see [source](https://github.com/nodejs/node/blob/v20.12.2/lib/async_hooks.js)
|
||||
*/
|
||||
declare module "async_hooks" {
|
||||
/**
|
||||
* ```js
|
||||
* import { executionAsyncId } from 'node:async_hooks';
|
||||
* import fs from 'node:fs';
|
||||
*
|
||||
* console.log(executionAsyncId()); // 1 - bootstrap
|
||||
* const path = '.';
|
||||
* fs.open(path, 'r', (err, fd) => {
|
||||
* console.log(executionAsyncId()); // 6 - open()
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* The ID returned from `executionAsyncId()` is related to execution timing, not
|
||||
* causality (which is covered by `triggerAsyncId()`):
|
||||
*
|
||||
* ```js
|
||||
* const server = net.createServer((conn) => {
|
||||
* // Returns the ID of the server, not of the new connection, because the
|
||||
* // callback runs in the execution scope of the server's MakeCallback().
|
||||
* async_hooks.executionAsyncId();
|
||||
*
|
||||
* }).listen(port, () => {
|
||||
* // Returns the ID of a TickObject (process.nextTick()) because all
|
||||
* // callbacks passed to .listen() are wrapped in a nextTick().
|
||||
* async_hooks.executionAsyncId();
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* Promise contexts may not get precise `executionAsyncIds` by default.
|
||||
* See the section on [promise execution tracking](https://nodejs.org/docs/latest-v20.x/api/async_hooks.html#promise-execution-tracking).
|
||||
* @since v8.1.0
|
||||
* @return The `asyncId` of the current execution context. Useful to track when something calls.
|
||||
*/
|
||||
function executionAsyncId(): number;
|
||||
/**
|
||||
* Resource objects returned by `executionAsyncResource()` are most often internal
|
||||
* Node.js handle objects with undocumented APIs. Using any functions or properties
|
||||
* on the object is likely to crash your application and should be avoided.
|
||||
*
|
||||
* Using `executionAsyncResource()` in the top-level execution context will
|
||||
* return an empty object as there is no handle or request object to use,
|
||||
* but having an object representing the top-level can be helpful.
|
||||
*
|
||||
* ```js
|
||||
* import { open } from 'node:fs';
|
||||
* import { executionAsyncId, executionAsyncResource } from 'node:async_hooks';
|
||||
*
|
||||
* console.log(executionAsyncId(), executionAsyncResource()); // 1 {}
|
||||
* open(new URL(import.meta.url), 'r', (err, fd) => {
|
||||
* console.log(executionAsyncId(), executionAsyncResource()); // 7 FSReqWrap
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* This can be used to implement continuation local storage without the
|
||||
* use of a tracking `Map` to store the metadata:
|
||||
*
|
||||
* ```js
|
||||
* import { createServer } from 'node:http';
|
||||
* import {
|
||||
* executionAsyncId,
|
||||
* executionAsyncResource,
|
||||
* createHook,
|
||||
* } from 'async_hooks';
|
||||
* const sym = Symbol('state'); // Private symbol to avoid pollution
|
||||
*
|
||||
* createHook({
|
||||
* init(asyncId, type, triggerAsyncId, resource) {
|
||||
* const cr = executionAsyncResource();
|
||||
* if (cr) {
|
||||
* resource[sym] = cr[sym];
|
||||
* }
|
||||
* },
|
||||
* }).enable();
|
||||
*
|
||||
* const server = createServer((req, res) => {
|
||||
* executionAsyncResource()[sym] = { state: req.url };
|
||||
* setTimeout(function() {
|
||||
* res.end(JSON.stringify(executionAsyncResource()[sym]));
|
||||
* }, 100);
|
||||
* }).listen(3000);
|
||||
* ```
|
||||
* @since v13.9.0, v12.17.0
|
||||
* @return The resource representing the current execution. Useful to store data within the resource.
|
||||
*/
|
||||
function executionAsyncResource(): object;
|
||||
/**
|
||||
* ```js
|
||||
* const server = net.createServer((conn) => {
|
||||
* // The resource that caused (or triggered) this callback to be called
|
||||
* // was that of the new connection. Thus the return value of triggerAsyncId()
|
||||
* // is the asyncId of "conn".
|
||||
* async_hooks.triggerAsyncId();
|
||||
*
|
||||
* }).listen(port, () => {
|
||||
* // Even though all callbacks passed to .listen() are wrapped in a nextTick()
|
||||
* // the callback itself exists because the call to the server's .listen()
|
||||
* // was made. So the return value would be the ID of the server.
|
||||
* async_hooks.triggerAsyncId();
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* Promise contexts may not get valid `triggerAsyncId`s by default. See
|
||||
* the section on [promise execution tracking](https://nodejs.org/docs/latest-v20.x/api/async_hooks.html#promise-execution-tracking).
|
||||
* @return The ID of the resource responsible for calling the callback that is currently being executed.
|
||||
*/
|
||||
function triggerAsyncId(): number;
|
||||
interface HookCallbacks {
|
||||
/**
|
||||
* Called when a class is constructed that has the possibility to emit an asynchronous event.
|
||||
* @param asyncId A unique ID for the async resource
|
||||
* @param type The type of the async resource
|
||||
* @param triggerAsyncId The unique ID of the async resource in whose execution context this async resource was created
|
||||
* @param resource Reference to the resource representing the async operation, needs to be released during destroy
|
||||
*/
|
||||
init?(asyncId: number, type: string, triggerAsyncId: number, resource: object): void;
|
||||
/**
|
||||
* When an asynchronous operation is initiated or completes a callback is called to notify the user.
|
||||
* The before callback is called just before said callback is executed.
|
||||
* @param asyncId the unique identifier assigned to the resource about to execute the callback.
|
||||
*/
|
||||
before?(asyncId: number): void;
|
||||
/**
|
||||
* Called immediately after the callback specified in `before` is completed.
|
||||
*
|
||||
* If an uncaught exception occurs during execution of the callback, then `after` will run after the `'uncaughtException'` event is emitted or a `domain`'s handler runs.
|
||||
* @param asyncId the unique identifier assigned to the resource which has executed the callback.
|
||||
*/
|
||||
after?(asyncId: number): void;
|
||||
/**
|
||||
* Called when a promise has resolve() called. This may not be in the same execution id
|
||||
* as the promise itself.
|
||||
* @param asyncId the unique id for the promise that was resolve()d.
|
||||
*/
|
||||
promiseResolve?(asyncId: number): void;
|
||||
/**
|
||||
* Called after the resource corresponding to asyncId is destroyed
|
||||
* @param asyncId a unique ID for the async resource
|
||||
*/
|
||||
destroy?(asyncId: number): void;
|
||||
}
|
||||
interface AsyncHook {
|
||||
/**
|
||||
* Enable the callbacks for a given AsyncHook instance. If no callbacks are provided enabling is a noop.
|
||||
*/
|
||||
enable(): this;
|
||||
/**
|
||||
* Disable the callbacks for a given AsyncHook instance from the global pool of AsyncHook callbacks to be executed. Once a hook has been disabled it will not be called again until enabled.
|
||||
*/
|
||||
disable(): this;
|
||||
}
|
||||
/**
|
||||
* Registers functions to be called for different lifetime events of each async
|
||||
* operation.
|
||||
*
|
||||
* The callbacks `init()`/`before()`/`after()`/`destroy()` are called for the
|
||||
* respective asynchronous event during a resource's lifetime.
|
||||
*
|
||||
* All callbacks are optional. For example, if only resource cleanup needs to
|
||||
* be tracked, then only the `destroy` callback needs to be passed. The
|
||||
* specifics of all functions that can be passed to `callbacks` is in the `Hook Callbacks` section.
|
||||
*
|
||||
* ```js
|
||||
* import { createHook } from 'node:async_hooks';
|
||||
*
|
||||
* const asyncHook = createHook({
|
||||
* init(asyncId, type, triggerAsyncId, resource) { },
|
||||
* destroy(asyncId) { },
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* The callbacks will be inherited via the prototype chain:
|
||||
*
|
||||
* ```js
|
||||
* class MyAsyncCallbacks {
|
||||
* init(asyncId, type, triggerAsyncId, resource) { }
|
||||
* destroy(asyncId) {}
|
||||
* }
|
||||
*
|
||||
* class MyAddedCallbacks extends MyAsyncCallbacks {
|
||||
* before(asyncId) { }
|
||||
* after(asyncId) { }
|
||||
* }
|
||||
*
|
||||
* const asyncHook = async_hooks.createHook(new MyAddedCallbacks());
|
||||
* ```
|
||||
*
|
||||
* Because promises are asynchronous resources whose lifecycle is tracked
|
||||
* via the async hooks mechanism, the `init()`, `before()`, `after()`, and`destroy()` callbacks _must not_ be async functions that return promises.
|
||||
* @since v8.1.0
|
||||
* @param callbacks The `Hook Callbacks` to register
|
||||
* @return Instance used for disabling and enabling hooks
|
||||
*/
|
||||
function createHook(callbacks: HookCallbacks): AsyncHook;
|
||||
interface AsyncResourceOptions {
|
||||
/**
|
||||
* The ID of the execution context that created this async event.
|
||||
* @default executionAsyncId()
|
||||
*/
|
||||
triggerAsyncId?: number | undefined;
|
||||
/**
|
||||
* Disables automatic `emitDestroy` when the object is garbage collected.
|
||||
* This usually does not need to be set (even if `emitDestroy` is called
|
||||
* manually), unless the resource's `asyncId` is retrieved and the
|
||||
* sensitive API's `emitDestroy` is called with it.
|
||||
* @default false
|
||||
*/
|
||||
requireManualDestroy?: boolean | undefined;
|
||||
}
|
||||
/**
|
||||
* The class `AsyncResource` is designed to be extended by the embedder's async
|
||||
* resources. Using this, users can easily trigger the lifetime events of their
|
||||
* own resources.
|
||||
*
|
||||
* The `init` hook will trigger when an `AsyncResource` is instantiated.
|
||||
*
|
||||
* The following is an overview of the `AsyncResource` API.
|
||||
*
|
||||
* ```js
|
||||
* import { AsyncResource, executionAsyncId } from 'node:async_hooks';
|
||||
*
|
||||
* // AsyncResource() is meant to be extended. Instantiating a
|
||||
* // new AsyncResource() also triggers init. If triggerAsyncId is omitted then
|
||||
* // async_hook.executionAsyncId() is used.
|
||||
* const asyncResource = new AsyncResource(
|
||||
* type, { triggerAsyncId: executionAsyncId(), requireManualDestroy: false },
|
||||
* );
|
||||
*
|
||||
* // Run a function in the execution context of the resource. This will
|
||||
* // * establish the context of the resource
|
||||
* // * trigger the AsyncHooks before callbacks
|
||||
* // * call the provided function `fn` with the supplied arguments
|
||||
* // * trigger the AsyncHooks after callbacks
|
||||
* // * restore the original execution context
|
||||
* asyncResource.runInAsyncScope(fn, thisArg, ...args);
|
||||
*
|
||||
* // Call AsyncHooks destroy callbacks.
|
||||
* asyncResource.emitDestroy();
|
||||
*
|
||||
* // Return the unique ID assigned to the AsyncResource instance.
|
||||
* asyncResource.asyncId();
|
||||
*
|
||||
* // Return the trigger ID for the AsyncResource instance.
|
||||
* asyncResource.triggerAsyncId();
|
||||
* ```
|
||||
*/
|
||||
class AsyncResource {
|
||||
/**
|
||||
* AsyncResource() is meant to be extended. Instantiating a
|
||||
* new AsyncResource() also triggers init. If triggerAsyncId is omitted then
|
||||
* async_hook.executionAsyncId() is used.
|
||||
* @param type The type of async event.
|
||||
* @param triggerAsyncId The ID of the execution context that created
|
||||
* this async event (default: `executionAsyncId()`), or an
|
||||
* AsyncResourceOptions object (since v9.3.0)
|
||||
*/
|
||||
constructor(type: string, triggerAsyncId?: number | AsyncResourceOptions);
|
||||
/**
|
||||
* Binds the given function to the current execution context.
|
||||
* @since v14.8.0, v12.19.0
|
||||
* @param fn The function to bind to the current execution context.
|
||||
* @param type An optional name to associate with the underlying `AsyncResource`.
|
||||
*/
|
||||
static bind<Func extends (this: ThisArg, ...args: any[]) => any, ThisArg>(
|
||||
fn: Func,
|
||||
type?: string,
|
||||
thisArg?: ThisArg,
|
||||
): Func;
|
||||
/**
|
||||
* Binds the given function to execute to this `AsyncResource`'s scope.
|
||||
* @since v14.8.0, v12.19.0
|
||||
* @param fn The function to bind to the current `AsyncResource`.
|
||||
*/
|
||||
bind<Func extends (...args: any[]) => any>(fn: Func): Func;
|
||||
/**
|
||||
* Call the provided function with the provided arguments in the execution context
|
||||
* of the async resource. This will establish the context, trigger the AsyncHooks
|
||||
* before callbacks, call the function, trigger the AsyncHooks after callbacks, and
|
||||
* then restore the original execution context.
|
||||
* @since v9.6.0
|
||||
* @param fn The function to call in the execution context of this async resource.
|
||||
* @param thisArg The receiver to be used for the function call.
|
||||
* @param args Optional arguments to pass to the function.
|
||||
*/
|
||||
runInAsyncScope<This, Result>(
|
||||
fn: (this: This, ...args: any[]) => Result,
|
||||
thisArg?: This,
|
||||
...args: any[]
|
||||
): Result;
|
||||
/**
|
||||
* Call all `destroy` hooks. This should only ever be called once. An error will
|
||||
* be thrown if it is called more than once. This **must** be manually called. If
|
||||
* the resource is left to be collected by the GC then the `destroy` hooks will
|
||||
* never be called.
|
||||
* @return A reference to `asyncResource`.
|
||||
*/
|
||||
emitDestroy(): this;
|
||||
/**
|
||||
* @return The unique `asyncId` assigned to the resource.
|
||||
*/
|
||||
asyncId(): number;
|
||||
/**
|
||||
* @return The same `triggerAsyncId` that is passed to the `AsyncResource` constructor.
|
||||
*/
|
||||
triggerAsyncId(): number;
|
||||
}
|
||||
/**
|
||||
* This class creates stores that stay coherent through asynchronous operations.
|
||||
*
|
||||
* While you can create your own implementation on top of the `node:async_hooks` module, `AsyncLocalStorage` should be preferred as it is a performant and memory
|
||||
* safe implementation that involves significant optimizations that are non-obvious
|
||||
* to implement.
|
||||
*
|
||||
* The following example uses `AsyncLocalStorage` to build a simple logger
|
||||
* that assigns IDs to incoming HTTP requests and includes them in messages
|
||||
* logged within each request.
|
||||
*
|
||||
* ```js
|
||||
* import http from 'node:http';
|
||||
* import { AsyncLocalStorage } from 'node:async_hooks';
|
||||
*
|
||||
* const asyncLocalStorage = new AsyncLocalStorage();
|
||||
*
|
||||
* function logWithId(msg) {
|
||||
* const id = asyncLocalStorage.getStore();
|
||||
* console.log(`${id !== undefined ? id : '-'}:`, msg);
|
||||
* }
|
||||
*
|
||||
* let idSeq = 0;
|
||||
* http.createServer((req, res) => {
|
||||
* asyncLocalStorage.run(idSeq++, () => {
|
||||
* logWithId('start');
|
||||
* // Imagine any chain of async operations here
|
||||
* setImmediate(() => {
|
||||
* logWithId('finish');
|
||||
* res.end();
|
||||
* });
|
||||
* });
|
||||
* }).listen(8080);
|
||||
*
|
||||
* http.get('http://localhost:8080');
|
||||
* http.get('http://localhost:8080');
|
||||
* // Prints:
|
||||
* // 0: start
|
||||
* // 1: start
|
||||
* // 0: finish
|
||||
* // 1: finish
|
||||
* ```
|
||||
*
|
||||
* Each instance of `AsyncLocalStorage` maintains an independent storage context.
|
||||
* Multiple instances can safely exist simultaneously without risk of interfering
|
||||
* with each other's data.
|
||||
* @since v13.10.0, v12.17.0
|
||||
*/
|
||||
class AsyncLocalStorage<T> {
|
||||
/**
|
||||
* Binds the given function to the current execution context.
|
||||
* @since v19.8.0
|
||||
* @experimental
|
||||
* @param fn The function to bind to the current execution context.
|
||||
* @return A new function that calls `fn` within the captured execution context.
|
||||
*/
|
||||
static bind<Func extends (...args: any[]) => any>(fn: Func): Func;
|
||||
/**
|
||||
* Captures the current execution context and returns a function that accepts a
|
||||
* function as an argument. Whenever the returned function is called, it
|
||||
* calls the function passed to it within the captured context.
|
||||
*
|
||||
* ```js
|
||||
* const asyncLocalStorage = new AsyncLocalStorage();
|
||||
* const runInAsyncScope = asyncLocalStorage.run(123, () => AsyncLocalStorage.snapshot());
|
||||
* const result = asyncLocalStorage.run(321, () => runInAsyncScope(() => asyncLocalStorage.getStore()));
|
||||
* console.log(result); // returns 123
|
||||
* ```
|
||||
*
|
||||
* AsyncLocalStorage.snapshot() can replace the use of AsyncResource for simple
|
||||
* async context tracking purposes, for example:
|
||||
*
|
||||
* ```js
|
||||
* class Foo {
|
||||
* #runInAsyncScope = AsyncLocalStorage.snapshot();
|
||||
*
|
||||
* get() { return this.#runInAsyncScope(() => asyncLocalStorage.getStore()); }
|
||||
* }
|
||||
*
|
||||
* const foo = asyncLocalStorage.run(123, () => new Foo());
|
||||
* console.log(asyncLocalStorage.run(321, () => foo.get())); // returns 123
|
||||
* ```
|
||||
* @since v19.8.0
|
||||
* @experimental
|
||||
* @return A new function with the signature `(fn: (...args) : R, ...args) : R`.
|
||||
*/
|
||||
static snapshot(): <R, TArgs extends any[]>(fn: (...args: TArgs) => R, ...args: TArgs) => R;
|
||||
/**
|
||||
* Disables the instance of `AsyncLocalStorage`. All subsequent calls
|
||||
* to `asyncLocalStorage.getStore()` will return `undefined` until `asyncLocalStorage.run()` or `asyncLocalStorage.enterWith()` is called again.
|
||||
*
|
||||
* When calling `asyncLocalStorage.disable()`, all current contexts linked to the
|
||||
* instance will be exited.
|
||||
*
|
||||
* Calling `asyncLocalStorage.disable()` is required before the `asyncLocalStorage` can be garbage collected. This does not apply to stores
|
||||
* provided by the `asyncLocalStorage`, as those objects are garbage collected
|
||||
* along with the corresponding async resources.
|
||||
*
|
||||
* Use this method when the `asyncLocalStorage` is not in use anymore
|
||||
* in the current process.
|
||||
* @since v13.10.0, v12.17.0
|
||||
* @experimental
|
||||
*/
|
||||
disable(): void;
|
||||
/**
|
||||
* Returns the current store.
|
||||
* If called outside of an asynchronous context initialized by
|
||||
* calling `asyncLocalStorage.run()` or `asyncLocalStorage.enterWith()`, it
|
||||
* returns `undefined`.
|
||||
* @since v13.10.0, v12.17.0
|
||||
*/
|
||||
getStore(): T | undefined;
|
||||
/**
|
||||
* Runs a function synchronously within a context and returns its
|
||||
* return value. The store is not accessible outside of the callback function.
|
||||
* The store is accessible to any asynchronous operations created within the
|
||||
* callback.
|
||||
*
|
||||
* The optional `args` are passed to the callback function.
|
||||
*
|
||||
* If the callback function throws an error, the error is thrown by `run()` too.
|
||||
* The stacktrace is not impacted by this call and the context is exited.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* ```js
|
||||
* const store = { id: 2 };
|
||||
* try {
|
||||
* asyncLocalStorage.run(store, () => {
|
||||
* asyncLocalStorage.getStore(); // Returns the store object
|
||||
* setTimeout(() => {
|
||||
* asyncLocalStorage.getStore(); // Returns the store object
|
||||
* }, 200);
|
||||
* throw new Error();
|
||||
* });
|
||||
* } catch (e) {
|
||||
* asyncLocalStorage.getStore(); // Returns undefined
|
||||
* // The error will be caught here
|
||||
* }
|
||||
* ```
|
||||
* @since v13.10.0, v12.17.0
|
||||
*/
|
||||
run<R>(store: T, callback: () => R): R;
|
||||
run<R, TArgs extends any[]>(store: T, callback: (...args: TArgs) => R, ...args: TArgs): R;
|
||||
/**
|
||||
* Runs a function synchronously outside of a context and returns its
|
||||
* return value. The store is not accessible within the callback function or
|
||||
* the asynchronous operations created within the callback. Any `getStore()` call done within the callback function will always return `undefined`.
|
||||
*
|
||||
* The optional `args` are passed to the callback function.
|
||||
*
|
||||
* If the callback function throws an error, the error is thrown by `exit()` too.
|
||||
* The stacktrace is not impacted by this call and the context is re-entered.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* ```js
|
||||
* // Within a call to run
|
||||
* try {
|
||||
* asyncLocalStorage.getStore(); // Returns the store object or value
|
||||
* asyncLocalStorage.exit(() => {
|
||||
* asyncLocalStorage.getStore(); // Returns undefined
|
||||
* throw new Error();
|
||||
* });
|
||||
* } catch (e) {
|
||||
* asyncLocalStorage.getStore(); // Returns the same object or value
|
||||
* // The error will be caught here
|
||||
* }
|
||||
* ```
|
||||
* @since v13.10.0, v12.17.0
|
||||
* @experimental
|
||||
*/
|
||||
exit<R, TArgs extends any[]>(callback: (...args: TArgs) => R, ...args: TArgs): R;
|
||||
/**
|
||||
* Transitions into the context for the remainder of the current
|
||||
* synchronous execution and then persists the store through any following
|
||||
* asynchronous calls.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* ```js
|
||||
* const store = { id: 1 };
|
||||
* // Replaces previous store with the given store object
|
||||
* asyncLocalStorage.enterWith(store);
|
||||
* asyncLocalStorage.getStore(); // Returns the store object
|
||||
* someAsyncOperation(() => {
|
||||
* asyncLocalStorage.getStore(); // Returns the same object
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* This transition will continue for the _entire_ synchronous execution.
|
||||
* This means that if, for example, the context is entered within an event
|
||||
* handler subsequent event handlers will also run within that context unless
|
||||
* specifically bound to another context with an `AsyncResource`. That is why `run()` should be preferred over `enterWith()` unless there are strong reasons
|
||||
* to use the latter method.
|
||||
*
|
||||
* ```js
|
||||
* const store = { id: 1 };
|
||||
*
|
||||
* emitter.on('my-event', () => {
|
||||
* asyncLocalStorage.enterWith(store);
|
||||
* });
|
||||
* emitter.on('my-event', () => {
|
||||
* asyncLocalStorage.getStore(); // Returns the same object
|
||||
* });
|
||||
*
|
||||
* asyncLocalStorage.getStore(); // Returns undefined
|
||||
* emitter.emit('my-event');
|
||||
* asyncLocalStorage.getStore(); // Returns the same object
|
||||
* ```
|
||||
* @since v13.11.0, v12.17.0
|
||||
* @experimental
|
||||
*/
|
||||
enterWith(store: T): void;
|
||||
}
|
||||
}
|
||||
declare module "node:async_hooks" {
|
||||
export * from "async_hooks";
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue