Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@onflow/util-actor

Package Overview
Dependencies
Maintainers
12
Versions
30
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@onflow/util-actor - npm Package Compare versions

Comparing version 1.3.0-alpha.0 to 1.3.0

.eslintrc.json

8

CHANGELOG.md
# @onflow/util-actor
## 1.3.0
### Minor Changes
- [#1728](https://github.com/onflow/fcl-js/pull/1728) [`a4f8c00c`](https://github.com/onflow/fcl-js/commit/a4f8c00c4cf292d3a4afac610dedbc89ff3affea) Thanks [@nialexsan](https://github.com/nialexsan)! - TS build
- [#1761](https://github.com/onflow/fcl-js/pull/1761) [`92b966d3`](https://github.com/onflow/fcl-js/commit/92b966d39936ba0a90629ee320e62e4fed5d2296) Thanks [@jribbink](https://github.com/jribbink)! - Enhance TS support for @onflow/util-actor
## 1.3.0-alpha.0

@@ -4,0 +12,0 @@

379

dist/actor.js

@@ -5,68 +5,24 @@ 'use strict';

/******************************************************************************
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
function __awaiter(thisArg, _arguments, P, generator) {
function adopt(value) {
return value instanceof P ? value : new P(function (resolve) {
resolve(value);
});
}
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) {
try {
step(generator.next(value));
} catch (e) {
reject(e);
const mailbox = () => {
const queue = [];
let next;
return {
async deliver(msg) {
queue.push(msg);
if (next) {
next(queue.shift());
next = undefined;
}
},
receive() {
return new Promise(function innerReceive(resolve) {
const msg = queue.shift();
if (msg) return resolve(msg);
next = resolve;
});
}
function rejected(value) {
try {
step(generator["throw"](value));
} catch (e) {
reject(e);
}
}
function step(result) {
result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
}
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
}
const mailbox = () => {
const queue = [];
var next;
return {
deliver(msg) {
return __awaiter(this, void 0, void 0, function* () {
queue.push(msg);
if (next) {
next(queue.shift());
next = undefined;
}
});
},
receive() {
return new Promise(function innerReceive(resolve) {
const msg = queue.shift();
if (msg)
return resolve(msg);
next = resolve;
});
},
};
};
};
// eslint-disable-next-line @typescript-eslint/no-var-requires
const queueMicrotask = require("queue-microtask");

@@ -80,141 +36,149 @@ const INIT = "INIT";

const TERMINATE = "TERMINATE";
const root = (typeof self === "object" && self.self === self && self) ||
(typeof global === "object" && global.global === global && global) ||
(typeof window === "object" && window.window === window && window) ||
{ FCL_REGISTRY: null };
const root = typeof self === "object" && self.self === self && self || typeof global === "object" && global.global === global && global || typeof window === "object" && window.window === window && window || {
FCL_REGISTRY: null
};
root.FCL_REGISTRY = root.FCL_REGISTRY == null ? {} : root.FCL_REGISTRY;
const FCL_REGISTRY = root.FCL_REGISTRY;
var pid = 0b0;
let pid = 0b0;
const DEFAULT_TIMEOUT = 5000;
const send = (addr, tag, data, opts = {}) => new Promise((reply, reject) => {
function send(addr, tag, data) {
let opts = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {
expectReply: false
};
return new Promise((resolve, reject) => {
const expectReply = opts.expectReply || false;
const timeout = opts.timeout != null ? opts.timeout : DEFAULT_TIMEOUT;
if (expectReply && timeout) {
setTimeout(() => reject(new Error(`Timeout: ${timeout}ms passed without a response.`)), timeout);
setTimeout(() => reject(new Error(`Timeout: ${timeout}ms passed without a response.`)), timeout);
}
const payload = {
to: addr,
from: opts.from,
tag,
data,
timeout,
reply,
reject,
to: addr,
from: opts.from,
tag,
data,
timeout,
reply: resolve,
reject
};
try {
FCL_REGISTRY[addr] &&
FCL_REGISTRY[addr].mailbox.deliver(payload);
if (!expectReply)
reply(true);
if (FCL_REGISTRY[addr]) {
FCL_REGISTRY[addr].mailbox.deliver(payload);
}
if (!expectReply) {
resolve(true);
}
} catch (error) {
console.error("FCL.Actor -- Could Not Deliver Message", payload, FCL_REGISTRY[addr], error);
reject(error);
}
catch (error) {
console.error("FCL.Actor -- Could Not Deliver Message", payload, FCL_REGISTRY[addr], error);
}
});
});
}
const kill = addr => {
delete FCL_REGISTRY[addr];
delete FCL_REGISTRY[addr];
};
const fromHandlers = (handlers = {}) => (ctx) => __awaiter(void 0, void 0, void 0, function* () {
if (typeof handlers[INIT] === "function")
yield handlers[INIT](ctx);
__loop: while (1) {
const letter = yield ctx.receive();
try {
if (letter.tag === EXIT) {
if (typeof handlers[TERMINATE] === "function") {
yield handlers[TERMINATE](ctx, letter, letter.data || {});
}
break __loop;
}
yield handlers[letter.tag](ctx, letter, letter.data || {});
const fromHandlers = handlers => async ctx => {
if (typeof handlers[INIT] === "function") await handlers[INIT](ctx);
__loop: while (1) {
const letter = await ctx.receive();
try {
if (letter.tag === EXIT) {
if (typeof handlers[TERMINATE] === "function") {
await handlers[TERMINATE](ctx, letter, letter.data || {});
}
catch (error) {
console.error(`${ctx.self()} Error`, letter, error);
}
finally {
continue __loop;
}
break __loop;
}
await handlers[letter.tag]?.(ctx, letter, letter.data || {});
} catch (error) {
console.error(`${ctx.self()} Error`, letter, error);
} finally {
continue __loop;
}
});
const parseAddr = (addr) => {
if (addr == null) {
return String(++pid);
}
return String(addr);
}
};
const spawn = (fn, rawAddr = null) => {
const addr = parseAddr(rawAddr);
if (FCL_REGISTRY[addr] != null)
return addr;
FCL_REGISTRY[addr] = {
addr,
mailbox: mailbox(),
subs: new Set(),
kvs: {},
error: null,
};
const ctx = {
self: () => addr,
receive: () => FCL_REGISTRY[addr].mailbox.receive(),
send: (to, tag, data, opts = {}) => {
opts.from = addr;
return send(to, tag, data, opts);
},
sendSelf: (tag, data, opts) => {
if (FCL_REGISTRY[addr])
send(addr, tag, data, opts);
},
broadcast: (tag, data, opts = {}) => {
opts.from = addr;
for (let to of FCL_REGISTRY[addr].subs)
send(to, tag, data, opts);
},
subscribe: sub => sub != null && FCL_REGISTRY[addr].subs.add(sub),
unsubscribe: sub => sub != null && FCL_REGISTRY[addr].subs.delete(sub),
subscriberCount: () => FCL_REGISTRY[addr].subs.size,
hasSubs: () => !!FCL_REGISTRY[addr].subs.size,
put: (key, value) => {
if (key != null)
FCL_REGISTRY[addr].kvs[key] = value;
},
get: (key, fallback) => {
const value = FCL_REGISTRY[addr].kvs[key];
return value == null ? fallback : value;
},
delete: key => {
delete FCL_REGISTRY[addr].kvs[key];
},
update: (key, fn) => {
if (key != null)
FCL_REGISTRY[addr].kvs[key] = fn(FCL_REGISTRY[addr].kvs[key]);
},
keys: () => {
return Object.keys(FCL_REGISTRY[addr].kvs);
},
all: () => {
return FCL_REGISTRY[addr].kvs;
},
where: pattern => {
return Object.keys(FCL_REGISTRY[addr].kvs).reduce((acc, key) => {
return pattern.test(key)
? Object.assign(Object.assign({}, acc), { [key]: FCL_REGISTRY[addr].kvs[key] }) : acc;
}, {});
},
merge: (data = {}) => {
Object.keys(data).forEach(key => (FCL_REGISTRY[addr].kvs[key] = data[key]));
},
fatalError: error => {
FCL_REGISTRY[addr].error = error;
for (let to of FCL_REGISTRY[addr].subs)
send(to, UPDATED);
},
};
if (typeof fn === "object")
fn = fromHandlers(fn);
queueMicrotask(() => __awaiter(void 0, void 0, void 0, function* () {
yield fn(ctx);
kill(addr);
}));
return addr;
const parseAddr = addr => {
if (addr == null) {
return String(++pid);
}
return String(addr);
};
const spawn = function (fnOrHandlers) {
let rawAddr = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
const addr = parseAddr(rawAddr);
if (FCL_REGISTRY[addr] != null) return addr;
FCL_REGISTRY[addr] = {
addr,
mailbox: mailbox(),
subs: new Set(),
kvs: {},
error: null
};
const ctx = createCtx(addr);
let fn;
if (typeof fnOrHandlers === "object") fn = fromHandlers(fnOrHandlers);else fn = fnOrHandlers;
queueMicrotask(async () => {
await fn(ctx);
kill(addr);
});
return addr;
};
const createCtx = addr => ({
self: () => addr,
receive: () => FCL_REGISTRY[addr].mailbox.receive(),
send: function (to, tag, data) {
let opts = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
if (to == null) return;
opts.from = addr;
return send(to, tag, data, opts);
},
sendSelf: function (tag, data) {
let opts = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
if (FCL_REGISTRY[addr]) send(addr, tag, data, opts);
},
broadcast: function (tag, data) {
let opts = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
opts.from = addr;
for (const to of FCL_REGISTRY[addr].subs) send(to, tag, data, opts);
},
subscribe: sub => sub != null && FCL_REGISTRY[addr].subs.add(sub),
unsubscribe: sub => sub != null && FCL_REGISTRY[addr].subs.delete(sub),
subscriberCount: () => FCL_REGISTRY[addr].subs.size,
hasSubs: () => !!FCL_REGISTRY[addr].subs.size,
put: (key, value) => {
if (key != null) FCL_REGISTRY[addr].kvs[key] = value;
},
get: function (key) {
let fallback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : undefined;
const value = FCL_REGISTRY[addr].kvs[key];
return value == null ? fallback : value;
},
delete: key => {
delete FCL_REGISTRY[addr].kvs[key];
},
update: (key, fn) => {
if (key != null) FCL_REGISTRY[addr].kvs[key] = fn(FCL_REGISTRY[addr].kvs[key]);
},
keys: () => {
return Object.keys(FCL_REGISTRY[addr].kvs);
},
all: () => {
return FCL_REGISTRY[addr].kvs;
},
where: pattern => {
return Object.keys(FCL_REGISTRY[addr].kvs).reduce((acc, key) => {
return pattern.test(key) ? {
...acc,
[key]: FCL_REGISTRY[addr].kvs[key]
} : acc;
}, {});
},
merge: function () {
let data = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
Object.keys(data).forEach(key => FCL_REGISTRY[addr].kvs[key] = data[key]);
},
fatalError: error => {
FCL_REGISTRY[addr].error = error;
for (const to of FCL_REGISTRY[addr].subs) send(to, UPDATED);
}
});
// Returns an unsubscribe function

@@ -229,23 +193,23 @@ // A SUBSCRIBE handler will need to be created to handle the subscription event

function subscriber(address, spawnFn, callback) {
spawnFn(address);
const EXIT = "@EXIT";
const self = spawn((ctx) => __awaiter(this, void 0, void 0, function* () {
ctx.send(address, SUBSCRIBE);
while (1) {
const letter = yield ctx.receive();
const error = FCL_REGISTRY[address].error;
if (letter.tag === EXIT) {
ctx.send(address, UNSUBSCRIBE);
return;
}
if (error) {
callback(null, error);
ctx.send(address, UNSUBSCRIBE);
return;
}
callback(letter.data, null);
}
}));
return () => send(self, EXIT);
spawnFn(address);
const self = spawn(async ctx => {
ctx.send(address, SUBSCRIBE);
while (1) {
const letter = await ctx.receive();
const error = FCL_REGISTRY[address].error;
if (letter.tag === EXIT) {
ctx.send(address, UNSUBSCRIBE);
return;
}
if (error) {
callback(null, error);
ctx.send(address, UNSUBSCRIBE);
return;
}
callback(letter.data, null);
}
});
return () => send(self, EXIT);
}
// Returns a promise that returns a result

@@ -259,4 +223,7 @@ // A SNAPSHOT handler will need to be created to handle the snapshot event

function snapshoter(address, spawnFn) {
spawnFn(address);
return send(address, SNAPSHOT, null, { expectReply: true, timeout: 0 });
spawnFn(address);
return send(address, SNAPSHOT, null, {
expectReply: true,
timeout: 0
});
}

@@ -263,0 +230,0 @@

@@ -1,67 +0,23 @@

/******************************************************************************
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
function __awaiter(thisArg, _arguments, P, generator) {
function adopt(value) {
return value instanceof P ? value : new P(function (resolve) {
resolve(value);
});
}
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) {
try {
step(generator.next(value));
} catch (e) {
reject(e);
const mailbox = () => {
const queue = [];
let next;
return {
async deliver(msg) {
queue.push(msg);
if (next) {
next(queue.shift());
next = undefined;
}
},
receive() {
return new Promise(function innerReceive(resolve) {
const msg = queue.shift();
if (msg) return resolve(msg);
next = resolve;
});
}
function rejected(value) {
try {
step(generator["throw"](value));
} catch (e) {
reject(e);
}
}
function step(result) {
result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
}
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
}
const mailbox = () => {
const queue = [];
var next;
return {
deliver(msg) {
return __awaiter(this, void 0, void 0, function* () {
queue.push(msg);
if (next) {
next(queue.shift());
next = undefined;
}
});
},
receive() {
return new Promise(function innerReceive(resolve) {
const msg = queue.shift();
if (msg)
return resolve(msg);
next = resolve;
});
},
};
};
};
// eslint-disable-next-line @typescript-eslint/no-var-requires
const queueMicrotask = require("queue-microtask");

@@ -75,141 +31,149 @@ const INIT = "INIT";

const TERMINATE = "TERMINATE";
const root = (typeof self === "object" && self.self === self && self) ||
(typeof global === "object" && global.global === global && global) ||
(typeof window === "object" && window.window === window && window) ||
{ FCL_REGISTRY: null };
const root = typeof self === "object" && self.self === self && self || typeof global === "object" && global.global === global && global || typeof window === "object" && window.window === window && window || {
FCL_REGISTRY: null
};
root.FCL_REGISTRY = root.FCL_REGISTRY == null ? {} : root.FCL_REGISTRY;
const FCL_REGISTRY = root.FCL_REGISTRY;
var pid = 0b0;
let pid = 0b0;
const DEFAULT_TIMEOUT = 5000;
const send = (addr, tag, data, opts = {}) => new Promise((reply, reject) => {
function send(addr, tag, data) {
let opts = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {
expectReply: false
};
return new Promise((resolve, reject) => {
const expectReply = opts.expectReply || false;
const timeout = opts.timeout != null ? opts.timeout : DEFAULT_TIMEOUT;
if (expectReply && timeout) {
setTimeout(() => reject(new Error(`Timeout: ${timeout}ms passed without a response.`)), timeout);
setTimeout(() => reject(new Error(`Timeout: ${timeout}ms passed without a response.`)), timeout);
}
const payload = {
to: addr,
from: opts.from,
tag,
data,
timeout,
reply,
reject,
to: addr,
from: opts.from,
tag,
data,
timeout,
reply: resolve,
reject
};
try {
FCL_REGISTRY[addr] &&
FCL_REGISTRY[addr].mailbox.deliver(payload);
if (!expectReply)
reply(true);
if (FCL_REGISTRY[addr]) {
FCL_REGISTRY[addr].mailbox.deliver(payload);
}
if (!expectReply) {
resolve(true);
}
} catch (error) {
console.error("FCL.Actor -- Could Not Deliver Message", payload, FCL_REGISTRY[addr], error);
reject(error);
}
catch (error) {
console.error("FCL.Actor -- Could Not Deliver Message", payload, FCL_REGISTRY[addr], error);
}
});
});
}
const kill = addr => {
delete FCL_REGISTRY[addr];
delete FCL_REGISTRY[addr];
};
const fromHandlers = (handlers = {}) => (ctx) => __awaiter(void 0, void 0, void 0, function* () {
if (typeof handlers[INIT] === "function")
yield handlers[INIT](ctx);
__loop: while (1) {
const letter = yield ctx.receive();
try {
if (letter.tag === EXIT) {
if (typeof handlers[TERMINATE] === "function") {
yield handlers[TERMINATE](ctx, letter, letter.data || {});
}
break __loop;
}
yield handlers[letter.tag](ctx, letter, letter.data || {});
const fromHandlers = handlers => async ctx => {
if (typeof handlers[INIT] === "function") await handlers[INIT](ctx);
__loop: while (1) {
const letter = await ctx.receive();
try {
if (letter.tag === EXIT) {
if (typeof handlers[TERMINATE] === "function") {
await handlers[TERMINATE](ctx, letter, letter.data || {});
}
catch (error) {
console.error(`${ctx.self()} Error`, letter, error);
}
finally {
continue __loop;
}
break __loop;
}
await handlers[letter.tag]?.(ctx, letter, letter.data || {});
} catch (error) {
console.error(`${ctx.self()} Error`, letter, error);
} finally {
continue __loop;
}
});
const parseAddr = (addr) => {
if (addr == null) {
return String(++pid);
}
return String(addr);
}
};
const spawn = (fn, rawAddr = null) => {
const addr = parseAddr(rawAddr);
if (FCL_REGISTRY[addr] != null)
return addr;
FCL_REGISTRY[addr] = {
addr,
mailbox: mailbox(),
subs: new Set(),
kvs: {},
error: null,
};
const ctx = {
self: () => addr,
receive: () => FCL_REGISTRY[addr].mailbox.receive(),
send: (to, tag, data, opts = {}) => {
opts.from = addr;
return send(to, tag, data, opts);
},
sendSelf: (tag, data, opts) => {
if (FCL_REGISTRY[addr])
send(addr, tag, data, opts);
},
broadcast: (tag, data, opts = {}) => {
opts.from = addr;
for (let to of FCL_REGISTRY[addr].subs)
send(to, tag, data, opts);
},
subscribe: sub => sub != null && FCL_REGISTRY[addr].subs.add(sub),
unsubscribe: sub => sub != null && FCL_REGISTRY[addr].subs.delete(sub),
subscriberCount: () => FCL_REGISTRY[addr].subs.size,
hasSubs: () => !!FCL_REGISTRY[addr].subs.size,
put: (key, value) => {
if (key != null)
FCL_REGISTRY[addr].kvs[key] = value;
},
get: (key, fallback) => {
const value = FCL_REGISTRY[addr].kvs[key];
return value == null ? fallback : value;
},
delete: key => {
delete FCL_REGISTRY[addr].kvs[key];
},
update: (key, fn) => {
if (key != null)
FCL_REGISTRY[addr].kvs[key] = fn(FCL_REGISTRY[addr].kvs[key]);
},
keys: () => {
return Object.keys(FCL_REGISTRY[addr].kvs);
},
all: () => {
return FCL_REGISTRY[addr].kvs;
},
where: pattern => {
return Object.keys(FCL_REGISTRY[addr].kvs).reduce((acc, key) => {
return pattern.test(key)
? Object.assign(Object.assign({}, acc), { [key]: FCL_REGISTRY[addr].kvs[key] }) : acc;
}, {});
},
merge: (data = {}) => {
Object.keys(data).forEach(key => (FCL_REGISTRY[addr].kvs[key] = data[key]));
},
fatalError: error => {
FCL_REGISTRY[addr].error = error;
for (let to of FCL_REGISTRY[addr].subs)
send(to, UPDATED);
},
};
if (typeof fn === "object")
fn = fromHandlers(fn);
queueMicrotask(() => __awaiter(void 0, void 0, void 0, function* () {
yield fn(ctx);
kill(addr);
}));
return addr;
const parseAddr = addr => {
if (addr == null) {
return String(++pid);
}
return String(addr);
};
const spawn = function (fnOrHandlers) {
let rawAddr = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
const addr = parseAddr(rawAddr);
if (FCL_REGISTRY[addr] != null) return addr;
FCL_REGISTRY[addr] = {
addr,
mailbox: mailbox(),
subs: new Set(),
kvs: {},
error: null
};
const ctx = createCtx(addr);
let fn;
if (typeof fnOrHandlers === "object") fn = fromHandlers(fnOrHandlers);else fn = fnOrHandlers;
queueMicrotask(async () => {
await fn(ctx);
kill(addr);
});
return addr;
};
const createCtx = addr => ({
self: () => addr,
receive: () => FCL_REGISTRY[addr].mailbox.receive(),
send: function (to, tag, data) {
let opts = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
if (to == null) return;
opts.from = addr;
return send(to, tag, data, opts);
},
sendSelf: function (tag, data) {
let opts = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
if (FCL_REGISTRY[addr]) send(addr, tag, data, opts);
},
broadcast: function (tag, data) {
let opts = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
opts.from = addr;
for (const to of FCL_REGISTRY[addr].subs) send(to, tag, data, opts);
},
subscribe: sub => sub != null && FCL_REGISTRY[addr].subs.add(sub),
unsubscribe: sub => sub != null && FCL_REGISTRY[addr].subs.delete(sub),
subscriberCount: () => FCL_REGISTRY[addr].subs.size,
hasSubs: () => !!FCL_REGISTRY[addr].subs.size,
put: (key, value) => {
if (key != null) FCL_REGISTRY[addr].kvs[key] = value;
},
get: function (key) {
let fallback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : undefined;
const value = FCL_REGISTRY[addr].kvs[key];
return value == null ? fallback : value;
},
delete: key => {
delete FCL_REGISTRY[addr].kvs[key];
},
update: (key, fn) => {
if (key != null) FCL_REGISTRY[addr].kvs[key] = fn(FCL_REGISTRY[addr].kvs[key]);
},
keys: () => {
return Object.keys(FCL_REGISTRY[addr].kvs);
},
all: () => {
return FCL_REGISTRY[addr].kvs;
},
where: pattern => {
return Object.keys(FCL_REGISTRY[addr].kvs).reduce((acc, key) => {
return pattern.test(key) ? {
...acc,
[key]: FCL_REGISTRY[addr].kvs[key]
} : acc;
}, {});
},
merge: function () {
let data = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
Object.keys(data).forEach(key => FCL_REGISTRY[addr].kvs[key] = data[key]);
},
fatalError: error => {
FCL_REGISTRY[addr].error = error;
for (const to of FCL_REGISTRY[addr].subs) send(to, UPDATED);
}
});
// Returns an unsubscribe function

@@ -224,23 +188,23 @@ // A SUBSCRIBE handler will need to be created to handle the subscription event

function subscriber(address, spawnFn, callback) {
spawnFn(address);
const EXIT = "@EXIT";
const self = spawn((ctx) => __awaiter(this, void 0, void 0, function* () {
ctx.send(address, SUBSCRIBE);
while (1) {
const letter = yield ctx.receive();
const error = FCL_REGISTRY[address].error;
if (letter.tag === EXIT) {
ctx.send(address, UNSUBSCRIBE);
return;
}
if (error) {
callback(null, error);
ctx.send(address, UNSUBSCRIBE);
return;
}
callback(letter.data, null);
}
}));
return () => send(self, EXIT);
spawnFn(address);
const self = spawn(async ctx => {
ctx.send(address, SUBSCRIBE);
while (1) {
const letter = await ctx.receive();
const error = FCL_REGISTRY[address].error;
if (letter.tag === EXIT) {
ctx.send(address, UNSUBSCRIBE);
return;
}
if (error) {
callback(null, error);
ctx.send(address, UNSUBSCRIBE);
return;
}
callback(letter.data, null);
}
});
return () => send(self, EXIT);
}
// Returns a promise that returns a result

@@ -254,4 +218,7 @@ // A SNAPSHOT handler will need to be created to handle the snapshot event

function snapshoter(address, spawnFn) {
spawnFn(address);
return send(address, SNAPSHOT, null, { expectReply: true, timeout: 0 });
spawnFn(address);
return send(address, SNAPSHOT, null, {
expectReply: true,
timeout: 0
});
}

@@ -258,0 +225,0 @@

(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["onflowUtil-actor"] = {}));
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["onflowUtil-actor"] = {}));
})(this, (function (exports) { 'use strict';
/******************************************************************************
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
function __awaiter(thisArg, _arguments, P, generator) {
function adopt(value) {
return value instanceof P ? value : new P(function (resolve) {
resolve(value);
const mailbox = () => {
const queue = [];
let next;
return {
async deliver(msg) {
queue.push(msg);
if (next) {
next(queue.shift());
next = undefined;
}
},
receive() {
return new Promise(function innerReceive(resolve) {
const msg = queue.shift();
if (msg) return resolve(msg);
next = resolve;
});
}
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) {
try {
step(generator.next(value));
} catch (e) {
reject(e);
}
};
};
// eslint-disable-next-line @typescript-eslint/no-var-requires
const queueMicrotask = require("queue-microtask");
const INIT = "INIT";
const SUBSCRIBE = "SUBSCRIBE";
const UNSUBSCRIBE = "UNSUBSCRIBE";
const UPDATED = "UPDATED";
const SNAPSHOT = "SNAPSHOT";
const EXIT = "EXIT";
const TERMINATE = "TERMINATE";
const root = typeof self === "object" && self.self === self && self || typeof global === "object" && global.global === global && global || typeof window === "object" && window.window === window && window || {
FCL_REGISTRY: null
};
root.FCL_REGISTRY = root.FCL_REGISTRY == null ? {} : root.FCL_REGISTRY;
const FCL_REGISTRY = root.FCL_REGISTRY;
let pid = 0b0;
const DEFAULT_TIMEOUT = 5000;
function send(addr, tag, data) {
let opts = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {
expectReply: false
};
return new Promise((resolve, reject) => {
const expectReply = opts.expectReply || false;
const timeout = opts.timeout != null ? opts.timeout : DEFAULT_TIMEOUT;
if (expectReply && timeout) {
setTimeout(() => reject(new Error(`Timeout: ${timeout}ms passed without a response.`)), timeout);
}
const payload = {
to: addr,
from: opts.from,
tag,
data,
timeout,
reply: resolve,
reject
};
try {
if (FCL_REGISTRY[addr]) {
FCL_REGISTRY[addr].mailbox.deliver(payload);
}
function rejected(value) {
try {
step(generator["throw"](value));
} catch (e) {
reject(e);
if (!expectReply) {
resolve(true);
}
} catch (error) {
console.error("FCL.Actor -- Could Not Deliver Message", payload, FCL_REGISTRY[addr], error);
reject(error);
}
});
}
const kill = addr => {
delete FCL_REGISTRY[addr];
};
const fromHandlers = handlers => async ctx => {
if (typeof handlers[INIT] === "function") await handlers[INIT](ctx);
__loop: while (1) {
const letter = await ctx.receive();
try {
if (letter.tag === EXIT) {
if (typeof handlers[TERMINATE] === "function") {
await handlers[TERMINATE](ctx, letter, letter.data || {});
}
break __loop;
}
function step(result) {
result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
}
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
await handlers[letter.tag]?.(ctx, letter, letter.data || {});
} catch (error) {
console.error(`${ctx.self()} Error`, letter, error);
} finally {
continue __loop;
}
}
const mailbox = () => {
const queue = [];
var next;
return {
deliver(msg) {
return __awaiter(this, void 0, void 0, function* () {
queue.push(msg);
if (next) {
next(queue.shift());
next = undefined;
}
});
},
receive() {
return new Promise(function innerReceive(resolve) {
const msg = queue.shift();
if (msg)
return resolve(msg);
next = resolve;
});
},
};
};
const parseAddr = addr => {
if (addr == null) {
return String(++pid);
}
return String(addr);
};
const spawn = function (fnOrHandlers) {
let rawAddr = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
const addr = parseAddr(rawAddr);
if (FCL_REGISTRY[addr] != null) return addr;
FCL_REGISTRY[addr] = {
addr,
mailbox: mailbox(),
subs: new Set(),
kvs: {},
error: null
};
const ctx = createCtx(addr);
let fn;
if (typeof fnOrHandlers === "object") fn = fromHandlers(fnOrHandlers);else fn = fnOrHandlers;
queueMicrotask(async () => {
await fn(ctx);
kill(addr);
});
return addr;
};
const createCtx = addr => ({
self: () => addr,
receive: () => FCL_REGISTRY[addr].mailbox.receive(),
send: function (to, tag, data) {
let opts = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
if (to == null) return;
opts.from = addr;
return send(to, tag, data, opts);
},
sendSelf: function (tag, data) {
let opts = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
if (FCL_REGISTRY[addr]) send(addr, tag, data, opts);
},
broadcast: function (tag, data) {
let opts = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
opts.from = addr;
for (const to of FCL_REGISTRY[addr].subs) send(to, tag, data, opts);
},
subscribe: sub => sub != null && FCL_REGISTRY[addr].subs.add(sub),
unsubscribe: sub => sub != null && FCL_REGISTRY[addr].subs.delete(sub),
subscriberCount: () => FCL_REGISTRY[addr].subs.size,
hasSubs: () => !!FCL_REGISTRY[addr].subs.size,
put: (key, value) => {
if (key != null) FCL_REGISTRY[addr].kvs[key] = value;
},
get: function (key) {
let fallback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : undefined;
const value = FCL_REGISTRY[addr].kvs[key];
return value == null ? fallback : value;
},
delete: key => {
delete FCL_REGISTRY[addr].kvs[key];
},
update: (key, fn) => {
if (key != null) FCL_REGISTRY[addr].kvs[key] = fn(FCL_REGISTRY[addr].kvs[key]);
},
keys: () => {
return Object.keys(FCL_REGISTRY[addr].kvs);
},
all: () => {
return FCL_REGISTRY[addr].kvs;
},
where: pattern => {
return Object.keys(FCL_REGISTRY[addr].kvs).reduce((acc, key) => {
return pattern.test(key) ? {
...acc,
[key]: FCL_REGISTRY[addr].kvs[key]
} : acc;
}, {});
},
merge: function () {
let data = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
Object.keys(data).forEach(key => FCL_REGISTRY[addr].kvs[key] = data[key]);
},
fatalError: error => {
FCL_REGISTRY[addr].error = error;
for (const to of FCL_REGISTRY[addr].subs) send(to, UPDATED);
}
});
const queueMicrotask = require("queue-microtask");
const INIT = "INIT";
const SUBSCRIBE = "SUBSCRIBE";
const UNSUBSCRIBE = "UNSUBSCRIBE";
const UPDATED = "UPDATED";
const SNAPSHOT = "SNAPSHOT";
const EXIT = "EXIT";
const TERMINATE = "TERMINATE";
const root = (typeof self === "object" && self.self === self && self) ||
(typeof global === "object" && global.global === global && global) ||
(typeof window === "object" && window.window === window && window) ||
{ FCL_REGISTRY: null };
root.FCL_REGISTRY = root.FCL_REGISTRY == null ? {} : root.FCL_REGISTRY;
const FCL_REGISTRY = root.FCL_REGISTRY;
var pid = 0b0;
const DEFAULT_TIMEOUT = 5000;
const send = (addr, tag, data, opts = {}) => new Promise((reply, reject) => {
const expectReply = opts.expectReply || false;
const timeout = opts.timeout != null ? opts.timeout : DEFAULT_TIMEOUT;
if (expectReply && timeout) {
setTimeout(() => reject(new Error(`Timeout: ${timeout}ms passed without a response.`)), timeout);
// Returns an unsubscribe function
// A SUBSCRIBE handler will need to be created to handle the subscription event
//
// [SUBSCRIBE]: (ctx, letter) => {
// ctx.subscribe(letter.from)
// ctx.send(letter.from, UPDATED, ctx.all())
// }
//
function subscriber(address, spawnFn, callback) {
spawnFn(address);
const self = spawn(async ctx => {
ctx.send(address, SUBSCRIBE);
while (1) {
const letter = await ctx.receive();
const error = FCL_REGISTRY[address].error;
if (letter.tag === EXIT) {
ctx.send(address, UNSUBSCRIBE);
return;
}
const payload = {
to: addr,
from: opts.from,
tag,
data,
timeout,
reply,
reject,
};
try {
FCL_REGISTRY[addr] &&
FCL_REGISTRY[addr].mailbox.deliver(payload);
if (!expectReply)
reply(true);
if (error) {
callback(null, error);
ctx.send(address, UNSUBSCRIBE);
return;
}
catch (error) {
console.error("FCL.Actor -- Could Not Deliver Message", payload, FCL_REGISTRY[addr], error);
}
callback(letter.data, null);
}
});
const kill = addr => {
delete FCL_REGISTRY[addr];
};
const fromHandlers = (handlers = {}) => (ctx) => __awaiter(void 0, void 0, void 0, function* () {
if (typeof handlers[INIT] === "function")
yield handlers[INIT](ctx);
__loop: while (1) {
const letter = yield ctx.receive();
try {
if (letter.tag === EXIT) {
if (typeof handlers[TERMINATE] === "function") {
yield handlers[TERMINATE](ctx, letter, letter.data || {});
}
break __loop;
}
yield handlers[letter.tag](ctx, letter, letter.data || {});
}
catch (error) {
console.error(`${ctx.self()} Error`, letter, error);
}
finally {
continue __loop;
}
}
return () => send(self, EXIT);
}
// Returns a promise that returns a result
// A SNAPSHOT handler will need to be created to handle the snapshot event
//
// [SNAPSHOT]: (ctx, letter) => {
// letter.reply(ctx.all())
// }
//
function snapshoter(address, spawnFn) {
spawnFn(address);
return send(address, SNAPSHOT, null, {
expectReply: true,
timeout: 0
});
const parseAddr = (addr) => {
if (addr == null) {
return String(++pid);
}
return String(addr);
};
const spawn = (fn, rawAddr = null) => {
const addr = parseAddr(rawAddr);
if (FCL_REGISTRY[addr] != null)
return addr;
FCL_REGISTRY[addr] = {
addr,
mailbox: mailbox(),
subs: new Set(),
kvs: {},
error: null,
};
const ctx = {
self: () => addr,
receive: () => FCL_REGISTRY[addr].mailbox.receive(),
send: (to, tag, data, opts = {}) => {
opts.from = addr;
return send(to, tag, data, opts);
},
sendSelf: (tag, data, opts) => {
if (FCL_REGISTRY[addr])
send(addr, tag, data, opts);
},
broadcast: (tag, data, opts = {}) => {
opts.from = addr;
for (let to of FCL_REGISTRY[addr].subs)
send(to, tag, data, opts);
},
subscribe: sub => sub != null && FCL_REGISTRY[addr].subs.add(sub),
unsubscribe: sub => sub != null && FCL_REGISTRY[addr].subs.delete(sub),
subscriberCount: () => FCL_REGISTRY[addr].subs.size,
hasSubs: () => !!FCL_REGISTRY[addr].subs.size,
put: (key, value) => {
if (key != null)
FCL_REGISTRY[addr].kvs[key] = value;
},
get: (key, fallback) => {
const value = FCL_REGISTRY[addr].kvs[key];
return value == null ? fallback : value;
},
delete: key => {
delete FCL_REGISTRY[addr].kvs[key];
},
update: (key, fn) => {
if (key != null)
FCL_REGISTRY[addr].kvs[key] = fn(FCL_REGISTRY[addr].kvs[key]);
},
keys: () => {
return Object.keys(FCL_REGISTRY[addr].kvs);
},
all: () => {
return FCL_REGISTRY[addr].kvs;
},
where: pattern => {
return Object.keys(FCL_REGISTRY[addr].kvs).reduce((acc, key) => {
return pattern.test(key)
? Object.assign(Object.assign({}, acc), { [key]: FCL_REGISTRY[addr].kvs[key] }) : acc;
}, {});
},
merge: (data = {}) => {
Object.keys(data).forEach(key => (FCL_REGISTRY[addr].kvs[key] = data[key]));
},
fatalError: error => {
FCL_REGISTRY[addr].error = error;
for (let to of FCL_REGISTRY[addr].subs)
send(to, UPDATED);
},
};
if (typeof fn === "object")
fn = fromHandlers(fn);
queueMicrotask(() => __awaiter(void 0, void 0, void 0, function* () {
yield fn(ctx);
kill(addr);
}));
return addr;
};
// Returns an unsubscribe function
// A SUBSCRIBE handler will need to be created to handle the subscription event
//
// [SUBSCRIBE]: (ctx, letter) => {
// ctx.subscribe(letter.from)
// ctx.send(letter.from, UPDATED, ctx.all())
// }
//
function subscriber(address, spawnFn, callback) {
spawnFn(address);
const EXIT = "@EXIT";
const self = spawn((ctx) => __awaiter(this, void 0, void 0, function* () {
ctx.send(address, SUBSCRIBE);
while (1) {
const letter = yield ctx.receive();
const error = FCL_REGISTRY[address].error;
if (letter.tag === EXIT) {
ctx.send(address, UNSUBSCRIBE);
return;
}
if (error) {
callback(null, error);
ctx.send(address, UNSUBSCRIBE);
return;
}
callback(letter.data, null);
}
}));
return () => send(self, EXIT);
}
// Returns a promise that returns a result
// A SNAPSHOT handler will need to be created to handle the snapshot event
//
// [SNAPSHOT]: (ctx, letter) => {
// letter.reply(ctx.all())
// }
//
function snapshoter(address, spawnFn) {
spawnFn(address);
return send(address, SNAPSHOT, null, { expectReply: true, timeout: 0 });
}
}
exports.EXIT = EXIT;
exports.INIT = INIT;
exports.SNAPSHOT = SNAPSHOT;
exports.SUBSCRIBE = SUBSCRIBE;
exports.TERMINATE = TERMINATE;
exports.UNSUBSCRIBE = UNSUBSCRIBE;
exports.UPDATED = UPDATED;
exports.kill = kill;
exports.send = send;
exports.snapshoter = snapshoter;
exports.spawn = spawn;
exports.subscriber = subscriber;
exports.EXIT = EXIT;
exports.INIT = INIT;
exports.SNAPSHOT = SNAPSHOT;
exports.SUBSCRIBE = SUBSCRIBE;
exports.TERMINATE = TERMINATE;
exports.UNSUBSCRIBE = UNSUBSCRIBE;
exports.UPDATED = UPDATED;
exports.kill = kill;
exports.send = send;
exports.snapshoter = snapshoter;
exports.spawn = spawn;
exports.subscriber = subscriber;
Object.defineProperty(exports, '__esModule', { value: true });
Object.defineProperty(exports, '__esModule', { value: true });
}));
//# sourceMappingURL=actor.umd.js.map
{
"name": "@onflow/util-actor",
"version": "1.3.0-alpha.0",
"version": "1.3.0",
"description": "A mechanism for forcing order/transitions of scoped async state",

@@ -16,3 +16,9 @@ "license": "Apache-2.0",

"devDependencies": {
"@onflow/fcl-bundle": "^1.4.0-alpha.0",
"@babel/preset-typescript": "^7.22.5",
"@onflow/fcl-bundle": "^1.4.0",
"@types/jest": "^29.5.3",
"@typescript-eslint/eslint-plugin": "^6.4.0",
"@typescript-eslint/parser": "^6.4.0",
"eslint": "^8.47.0",
"eslint-plugin-jsdoc": "^46.4.6",
"jest": "^29.5.0"

@@ -28,2 +34,3 @@ },

"unpkg": "dist/actor.umd.js",
"types": "dist/index.d.ts",
"scripts": {

@@ -34,4 +41,5 @@ "prepublishOnly": "npm test && npm run build",

"test:watch": "jest --watch",
"start": "fcl-bundle --watch"
"start": "fcl-bundle --watch",
"lint": "eslint src --ext .ts"
}
}

@@ -9,4 +9,4 @@ {

// next to the .js files
"outDir": "types",
"outDir": "types"
}
}
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc