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

@agoric/marshal

Package Overview
Dependencies
Maintainers
5
Versions
156
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@agoric/marshal - npm Package Compare versions

Comparing version 0.5.1-dev-f0e42b1.0 to 0.5.1-dev-f599585.0

src/deeplyFulfilled.js

38

index.js

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

export { PASS_STYLE, isObject } from './src/helpers/passStyleHelpers.js';
export { getErrorConstructor } from './src/helpers/error.js';
export { mapIterable, filterIterable } from './src/helpers/iter-helpers.js';
export {
PASS_STYLE,
isObject,
assertChecker,
getTag,
hasOwnPropertyOf,
} from './src/helpers/passStyle-helpers.js';
export { getErrorConstructor, toPassableError } from './src/helpers/error.js';
export {
getInterfaceOf,

@@ -8,15 +16,21 @@ ALLOW_IMPLICIT_REMOTABLES,

export { passStyleOf, everyPassableChild } from './src/passStyleOf.js';
export {
nameForPassableSymbol,
passableSymbolForName,
} from './src/helpers/symbol.js';
export { passStyleOf, assertPassable } from './src/passStyleOf.js';
export { pureCopy, sameValueZero } from './src/pureCopy.js';
export { deeplyFulfilled } from './src/deeplyFulfilled.js';
export { makeTagged } from './src/makeTagged.js';
export { Remotable, Far, ToFarFunction } from './src/make-far.js';
export { QCLASS, makeMarshal } from './src/marshal.js';
export { stringify, parse } from './src/marshal-stringify.js';
// Works, but not yet used
// export { decodeToJustin } from './src/marshal-justin.js';
export { pureCopy, Remotable, Far, ToFarFunction } from './src/make-far.js';
export { stringify, parse } from './src/marshal-stringify.js';
export {
isStructure,
assertStructure,
sameStructure,
fulfillToStructure,
} from './src/structure.js';
export {
assertRecord,

@@ -28,2 +42,2 @@ assertCopyArray,

isCopyArray,
} from './src/assertPassStyleOf.js';
} from './src/typeGuards.js';
{
"name": "@agoric/marshal",
"version": "0.5.1-dev-f0e42b1.0+f0e42b1",
"version": "0.5.1-dev-f599585.0+f599585",
"description": "marshal",

@@ -37,10 +37,9 @@ "type": "module",

"dependencies": {
"@agoric/assert": "0.3.16-dev-f0e42b1.0+f0e42b1",
"@agoric/eventual-send": "0.14.1-dev-f0e42b1.0+f0e42b1",
"@agoric/eventual-send": "0.14.1-dev-f599585.0+f599585",
"@agoric/nat": "^4.1.0",
"@agoric/promise-kit": "0.2.30-dev-f0e42b1.0+f0e42b1"
"@agoric/promise-kit": "0.2.30-dev-f599585.0+f599585"
},
"devDependencies": {
"@agoric/lockdown": "0.1.2-dev-f0e42b1.0+f0e42b1",
"@endo/ses-ava": "^0.2.8",
"@agoric/lockdown": "0.1.2-dev-f599585.0+f599585",
"@endo/ses-ava": "^0.2.13",
"ava": "^3.12.1",

@@ -72,3 +71,3 @@ "c8": "^7.7.2"

},
"gitHead": "f0e42b11046469bf29394c1bdd7ef1fb772f6474"
"gitHead": "f5995854229921788d94caa97107360130085e61"
}

@@ -7,5 +7,4 @@ /* eslint-disable no-use-before-define */

import { assert, details as X } from '@agoric/assert';
import { E } from '@agoric/eventual-send';
import { isObject } from './helpers/passStyleHelpers.js';
import { isObject } from './helpers/passStyle-helpers.js';
import { getInterfaceOf } from './helpers/remotable.js';

@@ -18,2 +17,3 @@ import { Far } from './make-far.js';

const { ownKeys } = Reflect;
const { details: X } = assert;

@@ -20,0 +20,0 @@ const makeConverter = (mirrorConverter = undefined) => {

@@ -8,4 +8,3 @@ // @ts-check

import './internal-types.js';
import '@agoric/assert/exported.js';
import { assertChecker, checkNormalProperty } from './passStyleHelpers.js';
import { assertChecker, checkNormalProperty } from './passStyle-helpers.js';

@@ -48,9 +47,4 @@ const { details: X } = assert;

// Recursively validate that each member is passable.
CopyArrayHelper.every(candidate, v => !!passStyleOfRecur(v));
candidate.every(v => !!passStyleOfRecur(v));
},
every: (passable, fn) =>
// Note that we explicitly call `fn` with only the arguments we want
// to provide.
passable.every((v, i) => fn(v, i)),
});

@@ -10,7 +10,6 @@ // @ts-check

checkNormalProperty,
} from './passStyleHelpers.js';
} from './passStyle-helpers.js';
import '../types.js';
import './internal-types.js';
import '@agoric/assert/exported.js';

@@ -22,3 +21,2 @@ const { details: X } = assert;

getOwnPropertyDescriptors,
entries,
prototype: objectPrototype,

@@ -67,9 +65,4 @@ } = Object;

// Recursively validate that each member is passable.
CopyRecordHelper.every(candidate, v => !!passStyleOfRecur(v));
Object.values(candidate).every(v => !!passStyleOfRecur(v));
},
every: (passable, fn) =>
// Note that we explicitly call `fn` with only the arguments we want
// to provide.
entries(passable).every(([k, v]) => fn(v, k)),
});

@@ -8,4 +8,3 @@ // @ts-check

import './internal-types.js';
import '@agoric/assert/exported.js';
import { assertChecker } from './passStyleHelpers.js';
import { assertChecker } from './passStyle-helpers.js';

@@ -99,4 +98,2 @@ const { details: X } = assert;

},
every: (_passable, _fn) => true,
});

@@ -103,0 +100,0 @@

@@ -30,8 +30,2 @@ // @ts-check

* ) => void} assertValid
*
* @property {(passable: Passable,
* fn: (passable: Passable, index: any) => boolean
* ) => boolean} every
* For recuring through the nested passable structure. Like
* `Array.prototype.every`, return `false` to stop early.
*/

@@ -8,3 +8,2 @@ // @ts-check

import './internal-types.js';
import '@agoric/assert/exported.js';
import {

@@ -18,3 +17,3 @@ assertChecker,

getTag,
} from './passStyleHelpers.js';
} from './passStyle-helpers.js';
import { getEnvironmentOption } from './environment-options.js';

@@ -21,0 +20,0 @@

@@ -6,4 +6,3 @@ // @ts-check

import { assert, details as X, q } from '@agoric/assert';
import { assertChecker, PASS_STYLE } from './helpers/passStyleHelpers.js';
import { assertChecker, PASS_STYLE } from './helpers/passStyle-helpers.js';
import {

@@ -14,4 +13,6 @@ assertIface,

} from './helpers/remotable.js';
import { passStyleOf } from './passStyleOf.js';
import { pureCopy } from './pureCopy.js';
const { quote: q, details: X } = assert;
const { prototype: functionPrototype } = Function;

@@ -27,69 +28,2 @@ const {

/**
* Do a deep copy of the object, handling Proxies and recursion.
* The resulting copy is guaranteed to be pure data, as well as hardened.
* Such a hardened, pure copy cannot be used as a communications path.
*
* @template {OnlyData} T
* @param {T} val input value. NOTE: Must be hardened!
* @returns {T} pure, hardened copy
*/
export const pureCopy = val => {
// passStyleOf now asserts that val has no pass-by-copy cycles.
const passStyle = passStyleOf(val);
switch (passStyle) {
case 'bigint':
case 'boolean':
case 'null':
case 'number':
case 'string':
case 'undefined':
case 'symbol':
return val;
case 'copyArray':
case 'copyRecord': {
const obj = /** @type {Object} */ (val);
// Create a new identity.
const copy = /** @type {T} */ (passStyle === 'copyArray' ? [] : {});
// Make a deep copy on the new identity.
// Object.entries(obj) takes a snapshot (even if a Proxy).
// Since we already know it is a copyRecord or copyArray, we
// know that Object.entries is safe enough. On a copyRecord it
// will represent all the own properties. On a copyArray it
// will represent all the own properties except for the length.
Object.entries(obj).forEach(([prop, value]) => {
copy[prop] = pureCopy(value);
});
return harden(copy);
}
case 'error': {
assert.fail(X`Errors cannot be copied: ${val}`, TypeError);
}
case 'remotable': {
assert.fail(
X`Input value ${q(
passStyle,
)} cannot be copied as it must be passed by reference`,
TypeError,
);
}
case 'promise': {
assert.fail(X`Promises cannot be copied`, TypeError);
}
default:
assert.fail(
X`Input value ${q(passStyle)} is not recognized as data`,
TypeError,
);
}
};
harden(pureCopy);
/**
* Now that the remotableProto does not provide its own `toString` method,

@@ -96,0 +30,0 @@ * ensure it always inherits from something. The original prototype of

@@ -7,3 +7,2 @@ // @ts-check

import { Nat } from '@agoric/nat';
import { assert, details as X, q } from '@agoric/assert';
import { QCLASS } from './marshal.js';

@@ -13,3 +12,4 @@

import { getErrorConstructor } from './helpers/error.js';
import { isObject } from './helpers/passStyleHelpers.js';
import { isObject } from './helpers/passStyle-helpers.js';
import { AtAtPrefixPattern, passableSymbolForName } from './helpers/symbol.js';

@@ -19,2 +19,3 @@ const { ownKeys } = Reflect;

const { stringify: quote } = JSON;
const { quote: q, details: X } = assert;

@@ -171,20 +172,14 @@ /**

}
case 'error': {
const { name, message } = rawTree;
assert.typeof(
name,
'string',
X`invalid error name typeof ${q(typeof name)}`,
);
assert(
getErrorConstructor(name) !== undefined,
X`Must be the name of an Error constructor ${name}`,
);
assert.typeof(
message,
'string',
X`invalid error message typeof ${q(typeof message)}`,
);
case 'symbol': {
const { name } = rawTree;
const sym = passableSymbolForName(name);
assert.typeof(sym, 'symbol');
return;
}
case 'tagged': {
const { tag, payload } = rawTree;
assert.typeof(tag, 'string');
prepare(payload);
return;
}
case 'slot': {

@@ -231,2 +226,20 @@ const { index, iface } = rawTree;

}
case 'error': {
const { name, message } = rawTree;
assert.typeof(
name,
'string',
X`invalid error name typeof ${q(typeof name)}`,
);
assert(
getErrorConstructor(name) !== undefined,
X`Must be the name of an Error constructor ${name}`,
);
assert.typeof(
message,
'string',
X`invalid error message typeof ${q(typeof message)}`,
);
return;
}

@@ -323,9 +336,25 @@ default: {

case '@@asyncIterator': {
// TODO deprecated. Eventually remove.
return out.next('Symbol.asyncIterator');
}
case 'error': {
const { name, message } = rawTree;
return out.next(`${name}(${quote(message)})`);
case 'symbol': {
const { name } = rawTree;
const sym = passableSymbolForName(name);
assert.typeof(sym, 'symbol');
const registeredName = Symbol.keyFor(sym);
if (registeredName === undefined) {
const match = AtAtPrefixPattern.exec(name);
assert(match !== null);
const suffix = match[1];
assert(Symbol[suffix] === sym);
return out.next(`Symbol[${quote(suffix)}]`);
}
return out.next(`Symbol.for(${quote(registeredName)})`);
}
case 'tagged': {
const { tag, payload } = rawTree;
out.next(`makeTagged(${quote(tag)},`);
decode(payload);
return out.next(')');
}

@@ -354,2 +383,7 @@ case 'slot': {

case 'error': {
const { name, message } = rawTree;
return out.next(`${name}(${quote(message)})`);
}
default: {

@@ -356,0 +390,0 @@ assert.fail(X`unrecognized ${q(QCLASS)} ${q(qclass)}`, TypeError);

// @ts-check
/// <reference types="ses"/>
import { assert, details as X } from '@agoric/assert';
import { makeMarshal } from './marshal.js';

@@ -8,2 +8,4 @@

const { details: X } = assert;
/** @type {ConvertValToSlot<any>} */

@@ -10,0 +12,0 @@ const doNotConvertValToSlot = val =>

@@ -7,3 +7,2 @@ // @ts-check

import { Nat } from '@agoric/nat';
import { assert, details as X, q } from '@agoric/assert';
import { passStyleOf } from './passStyleOf.js';

@@ -14,3 +13,9 @@

import { ErrorHelper, getErrorConstructor } from './helpers/error.js';
import { isObject } from './helpers/passStyleHelpers.js';
import { makeTagged } from './makeTagged.js';
import { isObject, getTag } from './helpers/passStyle-helpers.js';
import {
assertPassableSymbol,
nameForPassableSymbol,
passableSymbolForName,
} from './helpers/symbol.js';

@@ -20,2 +25,3 @@ const { ownKeys } = Reflect;

const { getOwnPropertyDescriptors, defineProperties, is, fromEntries } = Object;
const { details: X, quote: q } = assert;

@@ -140,6 +146,5 @@ /**

* Must encode `val` into plain JSON data *canonically*, such that
* `sameStructure(v1, v2)` implies
* `JSON.stringify(encode(v1)) === JSON.stringify(encode(v2))`
* For each record, we only accept sortable property names
* (no anonymous symbols). On the encoded form the sort
* `JSON.stringify(encode(v1)) === JSON.stringify(encode(v1))`
* For each copyRecord, we only accept string property names,
* not symbols. The encoded form the sort
* order of these names must be the same as their enumeration

@@ -192,12 +197,17 @@ * order, so a `JSON.stringify` of the encoded form agrees with

case 'symbol': {
switch (val) {
case Symbol.asyncIterator: {
return harden({
[QCLASS]: '@@asyncIterator',
});
}
default: {
assert.fail(X`Unsupported symbol ${q(String(val))}`);
}
assertPassableSymbol(val);
const name = /** @type {string} */ (nameForPassableSymbol(val));
if (name === '@@asyncIterator') {
// Deprectated qclass. TODO make conditional
// on environment variable. Eventually remove, but only after
// confident that all supported receivers understand
// `[QCLASS]: 'symbol'`.
return harden({
[QCLASS]: '@@asyncIterator',
});
}
return harden({
[QCLASS]: 'symbol',
name,
});
}

@@ -234,4 +244,10 @@ case 'copyRecord': {

}
case 'error': {
return encodeError(val);
case 'tagged': {
/** @type {Encoding} */
const result = harden({
[QCLASS]: 'tagged',
tag: getTag(val),
payload: encode(val.payload),
});
return result;
}

@@ -243,2 +259,5 @@ case 'remotable': {

}
case 'error': {
return encodeError(val);
}
case 'promise': {

@@ -354,5 +373,17 @@ // console.log(`serializeSlot: ${val}`);

case '@@asyncIterator': {
// Deprectated qclass. TODO make conditional
// on environment variable. Eventually remove, but after confident
// that there are no more supported senders.
return Symbol.asyncIterator;
}
case 'symbol': {
const { name } = rawTree;
return passableSymbolForName(name);
}
case 'tagged': {
const { tag, payload } = rawTree;
return makeTagged(tag, fullRevive(payload));
}
case 'error': {

@@ -376,2 +407,6 @@ const { name, message, errorId } = rawTree;

: `Remote${EC.name}(${errorId})`;
// Due to a defect in the SES type definition, the next line is
// fails a type check.
// Pending https://github.com/endojs/endo/issues/977
// @ts-ignore-next-line
const error = assert.error(`${message}`, EC, { errorName });

@@ -378,0 +413,0 @@ return error;

@@ -7,11 +7,13 @@ // @ts-check

import { isPromise } from '@agoric/promise-kit';
import { isObject, PASS_STYLE } from './helpers/passStyleHelpers.js';
import { isObject, PASS_STYLE } from './helpers/passStyle-helpers.js';
import { CopyArrayHelper } from './helpers/copyArray.js';
import { CopyRecordHelper } from './helpers/copyRecord.js';
import { TaggedHelper } from './helpers/tagged.js';
import { RemotableHelper } from './helpers/remotable.js';
import { ErrorHelper } from './helpers/error.js';
import { RemotableHelper } from './helpers/remotable.js';
import './types.js';
import './helpers/internal-types.js';
import { assertPassableSymbol } from './helpers/symbol.js';

@@ -30,5 +32,5 @@ const { details: X, quote: q } = assert;

* accidents.
* @returns {{passStyleOf: PassStyleOf, HelperTable: any}}
* @returns {PassStyleOf}
*/
const makePassStyleOfKit = passStyleHelpers => {
const makePassStyleOf = passStyleHelpers => {
const HelperTable = {

@@ -38,4 +40,5 @@ __proto__: null,

copyRecord: undefined,
tagged: undefined,
remotable: undefined,
error: undefined,
remotable: undefined,
};

@@ -120,6 +123,9 @@ for (const helper of passStyleHelpers) {

case 'number':
case 'bigint':
case 'symbol': {
case 'bigint': {
return typestr;
}
case 'symbol': {
assertPassableSymbol(inner);
return 'symbol';
}
case 'object': {

@@ -180,23 +186,16 @@ if (inner === null) {

};
return harden({ passStyleOf, HelperTable });
return harden(passStyleOf);
};
const { passStyleOf, HelperTable } = makePassStyleOfKit([
export const passStyleOf = makePassStyleOf([
CopyArrayHelper,
CopyRecordHelper,
TaggedHelper,
RemotableHelper,
ErrorHelper,
RemotableHelper,
]);
export { passStyleOf };
export const everyPassableChild = (passable, fn) => {
const passStyle = passStyleOf(passable);
const helper = HelperTable[passStyle];
if (helper) {
// everyPassable guards .every so that each helper only gets a
// genuine passable of its own flavor.
return helper.every(passable, fn);
}
return true;
export const assertPassable = val => {
passStyleOf(val); // throws if val is not a passable
};
harden(everyPassableChild);
harden(assertPassable);

@@ -9,4 +9,10 @@ // @ts-nocheck TODO Fix the recursive types to it checks. Will this

* @typedef { "undefined" | "null" |
* "boolean" | "number" | "bigint" | "string" | "symbol" |
* "copyArray" | "copyRecord" | "remotable" |
* "boolean" | "number" | "bigint" | "string" | "symbol"
* } PrimitiveStyle
*/
/**
* @typedef { PrimitiveStyle |
* "copyRecord" | "copyArray" | "tagged" |
* "remotable" |
* "error" | "promise"

@@ -28,6 +34,6 @@ * } PassStyle

* "boolean" | "number" | "bigint" | "string" | "symbol"),
* * the pass-by-copy containers ("copyArray" | "copyRecord") that
* * the pass-by-copy containers
* ("copyRecord" | "copyArray" | "tagged") that
* contain other Passables,
* * and the special cases ("error" | "promise"), which
* also contain other Passables.
* * and the special cases ("error" | "promise").
*

@@ -48,14 +54,3 @@ * A Passable's pass-by-copy superstructure ends in

/**
* @typedef {Passable} Structure
*
* A Passable is a Structure when it contains only
* * pass-by-copy primitives,
* * pass-by-copy containers,
* * remotables.
*
* Two Structures may be compared by for equivalence according to
* `sameStructure`, which is the strongest equivalence class supported by
* marshal's distributed object semantics.
*
* Two Structures can also be compared for full ordering,
* Two Passables can also be compared for total rank ordering,
* * where their passStyles are ordered according to the

@@ -79,10 +74,5 @@ * PassStyle typedef above.

/**
* @deprecated Renamed to `Structure`
* @typedef {Structure} Comparable
*/
/**
* @typedef {Structure} OnlyData
* @typedef {Passable} OnlyData
*
* A Structure is OnlyData when its pass-by-copy superstructure has no
* A Passable is OnlyData when its pass-by-copy superstructure has no
* remotables, i.e., when all the leaves of the data structure tree are

@@ -115,11 +105,19 @@ * primitive data types or empty composites.

/**
* @typedef {Passable} CopySet
* @template T
* @typedef {T[]} CopyArray
*/
/**
* @typedef {Passable} CopyMap
* @template T
* @typedef {Record<string, T>} CopyRecord
*/
/**
* @typedef {Passable} PatternNode
* @typedef {{
* [PASS_STYLE]: 'tagged',
* [Symbol.toStringTag]: string,
* payload: Passable
* }} CopyTagged
*
* The tag is the value of the `[String.toStringTag]` property.
*/

@@ -156,2 +154,3 @@

* EncodingClass<'@@asyncIterator'> |
* EncodingClass<'symbol'> & { name: string } |
* EncodingClass<'error'> & { name: string,

@@ -163,10 +162,12 @@ * message: string,

* EncodingClass<'hilbert'> & { original: Encoding,
* rest?: Encoding }
* rest?: Encoding
* } |
* EncodingClass<'tagged'> & { tag: string,
* payload: Encoding
* }
* } EncodingUnion
*
* @typedef {{ [index: string]: Encoding,
* '@qclass'?: undefined }
* } EncodingRecord
* '@qclass'?: undefined
* }} EncodingRecord
* We exclude '@qclass' as a property in encoding records.
*
* @typedef {EncodingUnion | null | string |

@@ -256,3 +257,2 @@ * boolean | number | EncodingRecord

* Simple semantics, just tell what interface (or undefined) a remotable has.
*
* @param {*} maybeRemotable the value to check

@@ -279,3 +279,2 @@ * @returns {InterfaceSpec|undefined} the interface specification, or undefined

* See the various uses for good examples.
*
* @param {boolean} cond

@@ -282,0 +281,0 @@ * @param {Details=} details

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