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

@bnaya/objectbuffer

Package Overview
Dependencies
Maintainers
1
Versions
122
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@bnaya/objectbuffer - npm Package Compare versions

Comparing version 0.0.0-dfae000 to 0.0.0-f1ba10a

2

dist/index.d.ts

@@ -9,3 +9,3 @@ /**

*/ /** */
export { createObjectBuffer, resizeObjectBuffer, getUnderlyingArrayBuffer, loadObjectBuffer, replaceUnderlyingArrayBuffer, sizeOf as unreliable_sizeOf, memoryStats, disposeWrapperObject, updateExternalArgs } from "./internal/api";
export { createObjectBuffer, resizeObjectBuffer, getUnderlyingArrayBuffer, loadObjectBuffer, replaceUnderlyingArrayBuffer, sizeOf as unreliable_sizeOf, memoryStats, disposeWrapperObject, updateExternalArgs, } from "./internal/api";
export { acquireLock, acquireLockWait, releaseLock } from "./internal/locks";

@@ -12,0 +12,0 @@ export declare type ExternalArgs = import("./internal/interfaces").ExternalArgsApi;

import { initializeArrayBuffer } from "./store";
import { objectSaver } from "./objectSaver";
import { createObjectWrapper } from "./objectWrapper";
import { arrayBufferCopyTo, externalArgsApiToExternalArgsApi, getInternalAPI } from "./utils";
import { arrayBufferCopyTo, externalArgsApiToExternalArgsApi, getInternalAPI, isPrimitive } from "./utils";
import { getCacheFor } from "./externalObjectsCache";
import { INITIAL_ENTRY_POINTER_TO_POINTER, MEM_POOL_START } from "./consts";
import { MemPool } from "@thi.ng/malloc";
import { UnsupportedOperationError } from "./exceptions";

@@ -15,2 +16,6 @@ /**

export function createObjectBuffer(externalArgs, size, initialValue, options = {}) {
if (Array.isArray(initialValue) || initialValue instanceof Date || initialValue instanceof Map || initialValue instanceof Set || isPrimitive(initialValue)) {
throw new UnsupportedOperationError();
}
const arrayBuffer = new (options.useSharedArrayBuffer ? SharedArrayBuffer : ArrayBuffer)(size);

@@ -32,3 +37,3 @@ initializeArrayBuffer(arrayBuffer);

};
const start = objectSaver(externalArgsApiToExternalArgsApi(externalArgs), carrier, [], initialValue);
const start = objectSaver(externalArgsApiToExternalArgsApi(externalArgs), carrier, [], new Map(), initialValue);
carrier.uint32[INITIAL_ENTRY_POINTER_TO_POINTER / Uint32Array.BYTES_PER_ELEMENT] = start;

@@ -35,0 +40,0 @@ return createObjectWrapper(externalArgsApiToExternalArgsApi(externalArgs), carrier, start);

@@ -7,3 +7,3 @@ import { ArrayEntry, ExternalArgs, GlobalCarrier } from "./interfaces";

} | undefined;
export declare function getFinalValueAtArrayIndex(externalArgs: ExternalArgs, dataViewCarrier: GlobalCarrier, pointerToArrayEntry: number, indexToGet: number): any;
export declare function getFinalValueAtArrayIndex(externalArgs: ExternalArgs, globalCarrier: GlobalCarrier, pointerToArrayEntry: number, indexToGet: number): any;
export declare function setValuePointerAtArrayIndex(carrier: GlobalCarrier, pointerToArrayEntry: number, indexToSet: number, pointerToEntry: number): void;

@@ -19,4 +19,4 @@ export declare function setValueAtArrayIndex(externalArgs: ExternalArgs, carrier: GlobalCarrier, pointerToArrayEntry: number, indexToSet: number, value: any): void;

export declare function shrinkArray(externalArgs: ExternalArgs, carrier: GlobalCarrier, pointerToArrayEntry: number, wishedLength: number): void;
export declare function arraySort(externalArgs: ExternalArgs, dataViewCarrier: GlobalCarrier, pointerToArrayEntry: number, sortComparator?: (a: any, b: any) => 1 | -1 | 0): void;
export declare function arraySort(externalArgs: ExternalArgs, globalCarrier: GlobalCarrier, pointerToArrayEntry: number, sortComparator?: (a: any, b: any) => 1 | -1 | 0): void;
export declare function arrayReverse(externalArgs: ExternalArgs, carrier: GlobalCarrier, pointerToArrayEntry: number): void;
//# sourceMappingURL=arrayHelpers.d.ts.map

@@ -23,4 +23,4 @@ import { readEntry, writeEntry, writeValueInPtrToPtrAndHandleMemory } from "./store";

}
export function getFinalValueAtArrayIndex(externalArgs, dataViewCarrier, pointerToArrayEntry, indexToGet) {
const pointers = arrayGetPointersToValueInIndex(dataViewCarrier, pointerToArrayEntry, indexToGet);
export function getFinalValueAtArrayIndex(externalArgs, globalCarrier, pointerToArrayEntry, indexToGet) {
const pointers = arrayGetPointersToValueInIndex(globalCarrier, pointerToArrayEntry, indexToGet);

@@ -31,3 +31,3 @@ if (pointers === undefined) {

return entryToFinalJavaScriptValue(externalArgs, dataViewCarrier, pointers.pointer);
return entryToFinalJavaScriptValue(externalArgs, globalCarrier, pointers.pointer);
}

@@ -105,7 +105,7 @@ export function setValuePointerAtArrayIndex(carrier, pointerToArrayEntry, indexToSet, pointerToEntry) {

export function arraySort(externalArgs, dataViewCarrier, pointerToArrayEntry, sortComparator = defaultCompareFunction) {
const metadata = arrayGetMetadata(dataViewCarrier, pointerToArrayEntry);
const pointersToValues = [...new Array(metadata.length).keys()].map(index => metadata.value + index * Uint32Array.BYTES_PER_ELEMENT).map(pointerToPointer => dataViewCarrier.uint32[pointerToPointer / Uint32Array.BYTES_PER_ELEMENT]);
export function arraySort(externalArgs, globalCarrier, pointerToArrayEntry, sortComparator = defaultCompareFunction) {
const metadata = arrayGetMetadata(globalCarrier, pointerToArrayEntry);
const pointersToValues = [...new Array(metadata.length).keys()].map(index => metadata.value + index * Uint32Array.BYTES_PER_ELEMENT).map(pointerToPointer => globalCarrier.uint32[pointerToPointer / Uint32Array.BYTES_PER_ELEMENT]);
const sortMe = pointersToValues.map(pointer => {
return [pointer, entryToFinalJavaScriptValue(externalArgs, dataViewCarrier, pointer)];
return [pointer, entryToFinalJavaScriptValue(externalArgs, globalCarrier, pointer)];
});

@@ -117,3 +117,3 @@ sortMe.sort((a, b) => {

for (let i = 0; i < sortMe.length; i += 1) {
dataViewCarrier.uint32[(metadata.value + i * Uint32Array.BYTES_PER_ELEMENT) / Uint32Array.BYTES_PER_ELEMENT] = sortMe[i][0];
globalCarrier.uint32[(metadata.value + i * Uint32Array.BYTES_PER_ELEMENT) / Uint32Array.BYTES_PER_ELEMENT] = sortMe[i][0];
}

@@ -120,0 +120,0 @@ } // https://stackoverflow.com/a/47349064/711152

@@ -15,3 +15,3 @@ import { appendEntry } from "./store";

for (const item of arrayToSave) {
const rOfValue = saveValue(externalArgs, carrier, referencedPointers, item);
const rOfValue = saveValue(externalArgs, carrier, referencedPointers, new Map(), item);
carrier.uint32[memoryForPointersCursor / Uint32Array.BYTES_PER_ELEMENT] = rOfValue;

@@ -18,0 +18,0 @@ memoryForPointersCursor += Uint32Array.BYTES_PER_ELEMENT;

import { ExternalArgs, GlobalCarrier } from "./interfaces";
export declare function arraySplice(externalArgs: ExternalArgs, dataViewCarrier: GlobalCarrier, pointerToArrayEntry: number, startArg: number, deleteCountArg?: number, ...itemsToAddArg: Array<any>): any[];
export declare function arraySplice(externalArgs: ExternalArgs, globalCarrier: GlobalCarrier, pointerToArrayEntry: number, startArg: number, deleteCountArg?: number, ...itemsToAddArg: Array<any>): any[];
//# sourceMappingURL=arraySplice.d.ts.map

@@ -5,8 +5,8 @@ import { arrayGetMetadata, getFinalValueAtArrayIndex, shrinkArray, extendArrayIfNeeded, arrayGetPointersToValueInIndex, setValuePointerAtArrayIndex } from "./arrayHelpers";

export function arraySplice(externalArgs, dataViewCarrier, pointerToArrayEntry, startArg, deleteCountArg, ...itemsToAddArg) {
const metadata = arrayGetMetadata(dataViewCarrier, pointerToArrayEntry);
export function arraySplice(externalArgs, globalCarrier, pointerToArrayEntry, startArg, deleteCountArg, ...itemsToAddArg) {
const metadata = arrayGetMetadata(globalCarrier, pointerToArrayEntry);
const calcedStart = calculateSpliceStart(metadata.length, startArg);
const calcedDeleteCount = calculateDeleteCount(metadata.length, calcedStart, deleteCountArg);
const newLength = metadata.length + itemsToAddArg.length - calcedDeleteCount;
extendArrayIfNeeded(externalArgs, dataViewCarrier, pointerToArrayEntry, newLength);
extendArrayIfNeeded(externalArgs, globalCarrier, pointerToArrayEntry, newLength);
const deletedItemsToReturn = []; // can be negative

@@ -17,3 +17,3 @@

for (let deletedItemIndexToSave = calcedStart; deletedItemIndexToSave < calcedStart + calcedDeleteCount; deletedItemIndexToSave += 1) {
deletedItemsToReturn.push(getFinalValueAtArrayIndex(externalArgs, dataViewCarrier, pointerToArrayEntry, deletedItemIndexToSave));
deletedItemsToReturn.push(getFinalValueAtArrayIndex(externalArgs, globalCarrier, pointerToArrayEntry, deletedItemIndexToSave));
} // copy-up items

@@ -30,6 +30,6 @@

for (let writeValueToIndex = newLength - 1; writeValueToIndex >= calcedStart + itemCountChange; writeValueToIndex -= 1) {
const valueToCopyPointers = arrayGetPointersToValueInIndex(dataViewCarrier, pointerToArrayEntry, writeValueToIndex - itemCountChange);
const valueToCopyPointers = arrayGetPointersToValueInIndex(globalCarrier, pointerToArrayEntry, writeValueToIndex - itemCountChange);
assertNonNull(valueToCopyPointers);
setValuePointerAtArrayIndex(dataViewCarrier, pointerToArrayEntry, writeValueToIndex, valueToCopyPointers.pointer);
dataViewCarrier.uint32[valueToCopyPointers.pointerToThePointer / Uint32Array.BYTES_PER_ELEMENT] = 0;
setValuePointerAtArrayIndex(globalCarrier, pointerToArrayEntry, writeValueToIndex, valueToCopyPointers.pointer);
globalCarrier.uint32[valueToCopyPointers.pointerToThePointer / Uint32Array.BYTES_PER_ELEMENT] = 0;
}

@@ -45,7 +45,7 @@ } // copy-down items

for (let writeValueToIndex = calcedStart + itemsToAddArg.length; writeValueToIndex < metadata.length + itemCountChange; writeValueToIndex += 1) {
const valueToCopyPointers = arrayGetPointersToValueInIndex(dataViewCarrier, pointerToArrayEntry, writeValueToIndex - itemCountChange);
const valueToCopyPointers = arrayGetPointersToValueInIndex(globalCarrier, pointerToArrayEntry, writeValueToIndex - itemCountChange);
assertNonNull(valueToCopyPointers);
setValuePointerAtArrayIndex(dataViewCarrier, pointerToArrayEntry, writeValueToIndex, valueToCopyPointers.pointer); // empty old array index, its still allocated!
setValuePointerAtArrayIndex(globalCarrier, pointerToArrayEntry, writeValueToIndex, valueToCopyPointers.pointer); // empty old array index, its still allocated!
dataViewCarrier.uint32[valueToCopyPointers.pointerToThePointer / Uint32Array.BYTES_PER_ELEMENT] = 0; // using that is wastefull
globalCarrier.uint32[valueToCopyPointers.pointerToThePointer / Uint32Array.BYTES_PER_ELEMENT] = 0; // using that is wastefull
// setValueAtArrayIndex(

@@ -64,9 +64,9 @@ // dataView,

for (let i = 0; i < itemsToAddArg.length; i += 1) {
const valueToSetPointers = arrayGetPointersToValueInIndex(dataViewCarrier, pointerToArrayEntry, calcedStart + i);
const valueToSetPointers = arrayGetPointersToValueInIndex(globalCarrier, pointerToArrayEntry, calcedStart + i);
assertNonNull(valueToSetPointers);
writeValueInPtrToPtr(externalArgs, dataViewCarrier, valueToSetPointers.pointerToThePointer, itemsToAddArg[i]);
writeValueInPtrToPtr(externalArgs, globalCarrier, valueToSetPointers.pointerToThePointer, itemsToAddArg[i]);
}
if (newLength < metadata.length) {
shrinkArray(externalArgs, dataViewCarrier, pointerToArrayEntry, newLength);
shrinkArray(externalArgs, globalCarrier, pointerToArrayEntry, newLength);
}

@@ -73,0 +73,0 @@

@@ -34,3 +34,3 @@ import { ExternalArgs, GlobalCarrier, ArrayEntry } from "./interfaces";

}
export declare function createArrayWrapper(externalArgs: ExternalArgs, dataViewCarrier: GlobalCarrier, entryPointer: number): Array<any>;
export declare function createArrayWrapper(externalArgs: ExternalArgs, globalCarrier: GlobalCarrier, entryPointer: number): Array<any>;
//# sourceMappingURL=arrayWrapper.d.ts.map

@@ -220,4 +220,4 @@ import { getFinalValueAtArrayIndex, arrayGetMetadata, setValueAtArrayIndex, arraySort, extendArrayIfNeeded, arrayReverse } from "./arrayHelpers";

}
export function createArrayWrapper(externalArgs, dataViewCarrier, entryPointer) {
return new Proxy([], new ArrayWrapper(externalArgs, dataViewCarrier, entryPointer));
export function createArrayWrapper(externalArgs, globalCarrier, entryPointer) {
return new Proxy([], new ArrayWrapper(externalArgs, globalCarrier, entryPointer));
}

@@ -15,4 +15,2 @@ import { ExternalArgs, GlobalCarrier, InternalAPI, DateEntry, ArrayEntry, ObjectEntry, MapEntry, SetEntry } from "./interfaces";

arrayAdditionalAllocation: number;
textDecoder: import("./textEncoderDecoderTypes").TextDecoder;
textEncoder: import("./textEncoderDecoderTypes").TextEncoder;
}>;

@@ -19,0 +17,0 @@ protected get entryPointer(): number;

@@ -16,3 +16,3 @@ import { WeakValueMap } from "./WeakValueMap";

function supportWeakRef() {
return typeof WeakRef !== "undefined";
return typeof WeakRef !== "undefined" && (typeof FinalizationGroup !== "undefined" || typeof "FinalizationRegistry" !== "undefined");
}
import { GlobalCarrier } from "./interfaces";
export declare function getAllLinkedAddresses(carrier: GlobalCarrier, ignoreRefCount: boolean, entryPointer: number): {
leafAddresses: number[];
arcAddresses: number[];
leafAddresses: Set<number>;
arcAddresses: Set<number>;
};
export declare function getObjectOrMapOrSetAddresses(carrier: GlobalCarrier, ignoreRefCount: boolean, internalHashmapPointer: number, leafAddresses: number[], arcAddresses: number[]): void;
export declare function getObjectOrMapOrSetAddresses(carrier: GlobalCarrier, internalHashmapPointer: number, leafAddresses: Set<number>, addressesToProcessQueue: number[]): void;
//# sourceMappingURL=getAllLinkedAddresses.d.ts.map

@@ -6,5 +6,17 @@ import { readEntry } from "./store";

export function getAllLinkedAddresses(carrier, ignoreRefCount, entryPointer) {
const leafAddresses = [];
const arcAddresses = [];
getAllLinkedAddressesStep(carrier, ignoreRefCount, entryPointer, leafAddresses, arcAddresses);
const leafAddresses = new Set();
const arcAddresses = new Set();
const addressesToProcessQueue = [entryPointer];
let addressToProcess = undefined; // const diffs = [];
while ((addressToProcess = addressesToProcessQueue.shift()) !== undefined) {
// const before = addressesToProcessQueue.slice();
if (addressToProcess === 0) {
continue;
}
getAllLinkedAddressesStep(carrier, ignoreRefCount, addressToProcess, leafAddresses, arcAddresses, addressesToProcessQueue); // diffs.push(addressesToProcessQueue.filter((p) => !before.includes(p)));
} // console.log(diffs);
return {

@@ -16,4 +28,4 @@ leafAddresses,

function getAllLinkedAddressesStep(carrier, ignoreRefCount, entryPointer, leafAddresses, arcAddresses) {
if (isKnownAddressValuePointer(entryPointer)) {
function getAllLinkedAddressesStep(carrier, ignoreRefCount, entryPointer, leafAddresses, arcAddresses, addressesToProcessQueue) {
if (isKnownAddressValuePointer(entryPointer) || leafAddresses.has(entryPointer) || arcAddresses.has(entryPointer)) {
return;

@@ -29,3 +41,3 @@ }

case ENTRY_TYPE.BIGINT_POSITIVE:
leafAddresses.push(entryPointer);
leafAddresses.add(entryPointer);
break;

@@ -37,6 +49,6 @@

if (entry.refsCount <= 1 || ignoreRefCount) {
leafAddresses.push(entryPointer);
getObjectOrMapOrSetAddresses(carrier, ignoreRefCount, entry.value, leafAddresses, arcAddresses);
leafAddresses.add(entryPointer);
getObjectOrMapOrSetAddresses(carrier, entry.value, leafAddresses, addressesToProcessQueue);
} else {
arcAddresses.push(entryPointer);
arcAddresses.add(entryPointer);
}

@@ -48,11 +60,11 @@

if (entry.refsCount <= 1 || ignoreRefCount) {
leafAddresses.push(entryPointer);
leafAddresses.push(entry.value);
leafAddresses.add(entryPointer);
leafAddresses.add(entry.value);
for (let i = 0; i < entry.allocatedLength; i += 1) {
const valuePointer = carrier.uint32[(entry.value + i * Uint32Array.BYTES_PER_ELEMENT) / Uint32Array.BYTES_PER_ELEMENT];
getAllLinkedAddressesStep(carrier, ignoreRefCount, valuePointer, leafAddresses, arcAddresses);
addressesToProcessQueue.push(valuePointer);
}
} else {
arcAddresses.push(entryPointer);
arcAddresses.add(entryPointer);
}

@@ -64,5 +76,5 @@

if (entry.refsCount <= 1 || ignoreRefCount) {
leafAddresses.push(entryPointer);
leafAddresses.add(entryPointer);
} else {
arcAddresses.push(entryPointer);
arcAddresses.add(entryPointer);
}

@@ -79,3 +91,3 @@

export function getObjectOrMapOrSetAddresses(carrier, ignoreRefCount, internalHashmapPointer, leafAddresses, arcAddresses) {
export function getObjectOrMapOrSetAddresses(carrier, internalHashmapPointer, leafAddresses, addressesToProcessQueue) {
const {

@@ -85,7 +97,10 @@ pointersToValuePointers,

} = hashMapGetPointersToFree(carrier, internalHashmapPointer);
leafAddresses.push(...pointers);
for (const leafPointer of pointers) {
leafAddresses.add(leafPointer);
}
for (const pointer of pointersToValuePointers) {
getAllLinkedAddressesStep(carrier, ignoreRefCount, carrier.uint32[pointer / Uint32Array.BYTES_PER_ELEMENT], leafAddresses, arcAddresses);
addressesToProcessQueue.push(carrier.uint32[pointer / Uint32Array.BYTES_PER_ELEMENT]);
}
}
import { ENTRY_TYPE } from "./entry-types";
import { TextDecoder, TextEncoder } from "./textEncoderDecoderTypes";
export declare type primitive = string | number | bigint | boolean | undefined | null;

@@ -72,5 +71,7 @@ export declare type Entry = StringEntry | NumberEntry | BigIntPositiveEntry | BigIntNegativeEntry | ObjectEntry | ArrayEntry | DateEntry | MapEntry | SetEntry;

hashMapMinInitialCapacity: number;
/**
* Allocate additional memory for array pointers,
* will prevent the reallocation and copy when array is getting bigger
*/
arrayAdditionalAllocation: number;
textDecoder: TextDecoder;
textEncoder: TextEncoder;
}>;

@@ -81,4 +82,2 @@ export declare type ExternalArgsApi = Readonly<{

arrayAdditionalAllocation?: number;
textDecoder: TextDecoder;
textEncoder: TextEncoder;
}>;

@@ -85,0 +84,0 @@ export interface InternalAPI {

@@ -20,3 +20,3 @@ import { ExternalArgs, GlobalCarrier, MapEntry, InternalAPI } from "./interfaces";

}
export declare function createMapWrapper<K extends string | number, V>(externalArgs: ExternalArgs, dataViewCarrier: GlobalCarrier, entryPointer: number): Map<K, V>;
export declare function createMapWrapper<K extends string | number, V>(externalArgs: ExternalArgs, globalCarrier: GlobalCarrier, entryPointer: number): Map<K, V>;
//# sourceMappingURL=mapWrapper.d.ts.map

@@ -100,4 +100,4 @@ import { deleteObjectPropertyEntryByKey, objectGet, objectSet, mapOrSetClear } from "./objectWrapperHelpers";

}
export function createMapWrapper(externalArgs, dataViewCarrier, entryPointer) {
return new MapWrapper(externalArgs, dataViewCarrier, entryPointer);
export function createMapWrapper(externalArgs, globalCarrier, entryPointer) {
return new MapWrapper(externalArgs, globalCarrier, entryPointer);
}
import { ExternalArgs, GlobalCarrier } from "./interfaces";
export declare function objectSaver(externalArgs: ExternalArgs, carrier: GlobalCarrier, referencedPointers: number[], objectToSave: any): number;
export declare function mapSaver(externalArgs: ExternalArgs, carrier: GlobalCarrier, referencedPointers: number[], mapToSave: Map<string | number, any>): number;
export declare function objectSaver(externalArgs: ExternalArgs, carrier: GlobalCarrier, referencedPointers: number[], visitedValues: Map<object, number>, objectToSave: any): number;
export declare function mapSaver(externalArgs: ExternalArgs, carrier: GlobalCarrier, referencedPointers: number[], visitedValues: Map<object, number>, mapToSave: Map<string | number, any>): number;
export declare function setSaver(externalArgs: ExternalArgs, carrier: GlobalCarrier, setToSave: Set<string | number>): number;
//# sourceMappingURL=objectSaver.d.ts.map

@@ -5,9 +5,9 @@ import { appendEntry } from "./store";

import { createHashMap, hashMapInsertUpdate } from "./hashmap/hashmap";
export function objectSaver(externalArgs, carrier, referencedPointers, objectToSave) {
export function objectSaver(externalArgs, carrier, referencedPointers, visitedValues, objectToSave) {
const objectEntries = Object.entries(objectToSave);
const hashMapPointer = createHashMap(carrier, Math.max(externalArgs.hashMapMinInitialCapacity, objectEntries.length * 1.3));
const hashMapPointer = createHashMap(carrier, Math.max(externalArgs.hashMapMinInitialCapacity, Math.ceil(objectEntries.length * 1.3)));
for (const [key, value] of objectEntries) {
const ptrToPtr = hashMapInsertUpdate(externalArgs, carrier, hashMapPointer, key);
const pointerToValue = saveValue(externalArgs, carrier, referencedPointers, value);
const pointerToValue = saveValue(externalArgs, carrier, referencedPointers, visitedValues, value);
carrier.uint32[ptrToPtr / Uint32Array.BYTES_PER_ELEMENT] = pointerToValue;

@@ -23,8 +23,8 @@ }

}
export function mapSaver(externalArgs, carrier, referencedPointers, mapToSave) {
const hashMapPointer = createHashMap(carrier, Math.max(externalArgs.hashMapMinInitialCapacity, mapToSave.size * 1.3));
export function mapSaver(externalArgs, carrier, referencedPointers, visitedValues, mapToSave) {
const hashMapPointer = createHashMap(carrier, Math.max(externalArgs.hashMapMinInitialCapacity, Math.ceil(mapToSave.size * 1.3)));
for (const [key, value] of mapToSave.entries()) {
const ptrToPtr = hashMapInsertUpdate(externalArgs, carrier, hashMapPointer, key);
const pointerToValue = saveValue(externalArgs, carrier, referencedPointers, value);
const pointerToValue = saveValue(externalArgs, carrier, referencedPointers, visitedValues, value);
carrier.uint32[ptrToPtr / Uint32Array.BYTES_PER_ELEMENT] = pointerToValue;

@@ -41,3 +41,3 @@ }

export function setSaver(externalArgs, carrier, setToSave) {
const hashMapPointer = createHashMap(carrier, Math.max(externalArgs.hashMapMinInitialCapacity, setToSave.size * 1.3));
const hashMapPointer = createHashMap(carrier, Math.max(externalArgs.hashMapMinInitialCapacity, Math.ceil(setToSave.size * 1.3)));

@@ -44,0 +44,0 @@ for (const key of setToSave.keys()) {

@@ -19,3 +19,3 @@ import { ObjectEntry, ExternalArgs, GlobalCarrier } from "./interfaces";

}
export declare function createObjectWrapper<T = any>(externalArgs: ExternalArgs, dataViewCarrier: GlobalCarrier, entryPointer: number): T;
export declare function createObjectWrapper<T = any>(externalArgs: ExternalArgs, globalCarrier: GlobalCarrier, entryPointer: number): T;
//# sourceMappingURL=objectWrapper.d.ts.map

@@ -97,6 +97,6 @@ import { getObjectPropertiesEntries, deleteObjectPropertyEntryByKey, objectGet, objectSet } from "./objectWrapperHelpers";

}
export function createObjectWrapper(externalArgs, dataViewCarrier, entryPointer) {
export function createObjectWrapper(externalArgs, globalCarrier, entryPointer) {
return new Proxy({
objectBufferWrapper: "objectBufferWrapper"
}, new ObjectWrapper(externalArgs, dataViewCarrier, entryPointer));
}, new ObjectWrapper(externalArgs, globalCarrier, entryPointer));
}

@@ -9,4 +9,3 @@ import { ExternalArgs, GlobalCarrier } from "./interfaces";

export declare function objectGet(externalArgs: ExternalArgs, carrier: GlobalCarrier, entryPointer: number, key: string | number): any;
export declare function hashmapClearFree(externalArgs: ExternalArgs, carrier: GlobalCarrier, hashmapPointer: number): void;
export declare function mapOrSetClear(externalArgs: ExternalArgs, carrier: GlobalCarrier, mapOrSetPtr: number): void;
//# sourceMappingURL=objectWrapperHelpers.d.ts.map

@@ -1,5 +0,5 @@

import { readEntry, writeValueInPtrToPtrAndHandleMemory, handleArcForDeletedValuePointer, decrementRefCount, writeEntry } from "./store";
import { readEntry, writeValueInPtrToPtrAndHandleMemory, handleArcForDeletedValuePointer, decrementRefCount, writeEntry, setRefCount } from "./store";
import { entryToFinalJavaScriptValue } from "./entryToFinalJavaScriptValue";
import { hashMapDelete, hashMapLowLevelIterator, hashMapNodePointerToKeyValue, hashMapInsertUpdate, hashMapValueLookup, createHashMap } from "./hashmap/hashmap";
import { getObjectOrMapOrSetAddresses } from "./getAllLinkedAddresses";
import { getAllLinkedAddresses } from "./getAllLinkedAddresses";
export function deleteObjectPropertyEntryByKey(externalArgs, carrier, hashmapPointer, keyToDeleteBy) {

@@ -46,9 +46,38 @@ const deletedValuePointerToPointer = hashMapDelete(carrier, hashmapPointer, keyToDeleteBy); // no such key

return entryToFinalJavaScriptValue(externalArgs, carrier, carrier.uint32[valuePointer / Uint32Array.BYTES_PER_ELEMENT]);
}
export function hashmapClearFree(externalArgs, carrier, hashmapPointer) {
const leafAddresses = [];
const arcAddresses = [];
getObjectOrMapOrSetAddresses(carrier, false, hashmapPointer, leafAddresses, arcAddresses);
} // export function hashmapClearFree(
// externalArgs: ExternalArgs,
// carrier: GlobalCarrier,
// hashmapPointer: number
// ) {
// const leafAddresses = new Set<number>();
// const addressesToProcessQueue: number[] = [];
// getObjectOrMapOrSetAddresses(
// carrier,
// hashmapPointer,
// leafAddresses,
// addressesToProcessQueue
// );
// for (const address of leafAddresses) {
// carrier.allocator.free(address);
// }
// for (const address of arcAddresses) {
// decrementRefCount(externalArgs, carrier, address);
// }
// }
export function mapOrSetClear(externalArgs, carrier, mapOrSetPtr) {
const entry = readEntry(carrier, mapOrSetPtr); // we fake the entry refCount as zero so getAllLinkedAddresses will visit what's needed
const prevCount = setRefCount(carrier, mapOrSetPtr, 0);
const {
leafAddresses,
arcAddresses
} = getAllLinkedAddresses(carrier, false, mapOrSetPtr);
for (const address of leafAddresses) {
// don't dispose the address we need to reuse
if (address === mapOrSetPtr) {
continue;
}
carrier.allocator.free(address);

@@ -58,10 +87,15 @@ }

for (const address of arcAddresses) {
// don't dispose the address we need to reuse
if (address === mapOrSetPtr) {
continue;
}
decrementRefCount(externalArgs, carrier, address);
}
}
export function mapOrSetClear(externalArgs, carrier, mapOrSetPtr) {
const entry = readEntry(carrier, mapOrSetPtr);
hashmapClearFree(externalArgs, carrier, entry.value);
} // hashmapClearFree(externalArgs, carrier, entry.value);
// Restore real ref count
setRefCount(carrier, mapOrSetPtr, prevCount);
entry.value = createHashMap(carrier, externalArgs.hashMapMinInitialCapacity);
writeEntry(carrier, mapOrSetPtr, entry);
}

@@ -5,3 +5,3 @@ import { ExternalArgs, GlobalCarrier } from "./interfaces";

*/
export declare function saveValue(externalArgs: ExternalArgs, carrier: GlobalCarrier, referencedPointers: number[], value: any): number;
export declare function saveValue(externalArgs: ExternalArgs, carrier: GlobalCarrier, referencedPointers: number[], visitedValuesOnCurrentSaveOperation: Map<object, number>, value: any): number;
//# sourceMappingURL=saveValue.d.ts.map

@@ -11,3 +11,4 @@ import { primitiveValueToEntry, isPrimitive, getOurPointerIfApplicable } from "./utils";

export function saveValue(externalArgs, carrier, referencedPointers, value) {
export function saveValue(externalArgs, carrier, referencedPointers, // Not really working yet. we need iterative saving for it
visitedValuesOnCurrentSaveOperation, value) {
let valuePointer = 0;

@@ -38,2 +39,5 @@ let maybeOurPointer;

referencedPointers.push(valuePointer);
} else if (maybeOurPointer = visitedValuesOnCurrentSaveOperation.get(value)) {
valuePointer = maybeOurPointer;
referencedPointers.push(valuePointer);
} else if (Array.isArray(value)) {

@@ -48,7 +52,10 @@ valuePointer = arraySaver(externalArgs, carrier, referencedPointers, value);

} else if (value instanceof Map) {
valuePointer = mapSaver(externalArgs, carrier, referencedPointers, value);
valuePointer = mapSaver(externalArgs, carrier, referencedPointers, visitedValuesOnCurrentSaveOperation, value);
visitedValuesOnCurrentSaveOperation.set(value, valuePointer);
} else if (value instanceof Set) {
valuePointer = setSaver(externalArgs, carrier, value);
visitedValuesOnCurrentSaveOperation.set(value, valuePointer);
} else if (typeof value === "object") {
valuePointer = objectSaver(externalArgs, carrier, referencedPointers, value);
valuePointer = objectSaver(externalArgs, carrier, referencedPointers, visitedValuesOnCurrentSaveOperation, value);
visitedValuesOnCurrentSaveOperation.set(value, valuePointer);
} else {

@@ -55,0 +62,0 @@ throw new Error("unsupported yet");

@@ -19,3 +19,3 @@ import { ExternalArgs, GlobalCarrier, MapEntry, InternalAPI } from "./interfaces";

}
export declare function createSetWrapper<K extends string | number>(externalArgs: ExternalArgs, dataViewCarrier: GlobalCarrier, entryPointer: number): Set<K>;
export declare function createSetWrapper<K extends string | number>(externalArgs: ExternalArgs, globalCarrier: GlobalCarrier, entryPointer: number): Set<K>;
//# sourceMappingURL=setWrapper.d.ts.map

@@ -88,4 +88,4 @@ import { deleteObjectPropertyEntryByKey, objectSet, mapOrSetClear } from "./objectWrapperHelpers";

}
export function createSetWrapper(externalArgs, dataViewCarrier, entryPointer) {
return new SetWrapper(externalArgs, dataViewCarrier, entryPointer);
export function createSetWrapper(externalArgs, globalCarrier, entryPointer) {
return new SetWrapper(externalArgs, globalCarrier, entryPointer);
}

@@ -18,2 +18,4 @@ import { Entry, primitive, GlobalCarrier } from "./interfaces";

export declare function decrementRefCount(externalArgs: ExternalArgs, carrier: GlobalCarrier, entryPointer: number): number;
export declare function getRefCount(carrier: GlobalCarrier, entryPointer: number): number;
export declare function setRefCount(carrier: GlobalCarrier, entryPointer: number, newRefCount: number): number;
export declare function getObjectValuePtrToPtr(pointerToEntry: number): number;

@@ -20,0 +22,0 @@ export declare function memComp(uint8: Uint8Array, aStart: number, bStart: number, length: number): boolean;

@@ -280,3 +280,3 @@ import { ENTRY_TYPE, isPrimitiveEntryType } from "./entry-types";

const referencedPointers = [];
const newEntryPointer = saveValue(externalArgs, carrier, referencedPointers, value);
const newEntryPointer = saveValue(externalArgs, carrier, referencedPointers, new Map(), value);
carrier.uint32[ptrToPtr / Uint32Array.BYTES_PER_ELEMENT] = newEntryPointer;

@@ -368,2 +368,23 @@ return {

throw new Error("unexpected");
}
export function getRefCount(carrier, entryPointer) {
const entry = readEntry(carrier, entryPointer);
if ("refsCount" in entry) {
return entry.refsCount;
}
throw new Error("unexpected");
}
export function setRefCount(carrier, entryPointer, newRefCount) {
const entry = readEntry(carrier, entryPointer);
if ("refsCount" in entry) {
const prevCount = entry.refsCount;
entry.refsCount = newRefCount;
writeEntry(carrier, entryPointer, entry);
return prevCount;
}
throw new Error("unexpected");
} // export function getObjectPropPtrToPtr(

@@ -370,0 +391,0 @@ // { dataView }: GlobalCarrier,

@@ -15,3 +15,4 @@ const KEYS = 1;

this.map = new Map();
this.group = new FinalizationGroup(iterator => {
const FinalizationSomething = typeof FinalizationRegistry !== "undefined" ? FinalizationRegistry : FinalizationGroup;
this.group = new FinalizationSomething(iterator => {
for (const key of iterator) {

@@ -18,0 +19,0 @@ this.map.delete(key);

@@ -9,3 +9,3 @@ /**

*/ /** */
export { createObjectBuffer, resizeObjectBuffer, getUnderlyingArrayBuffer, loadObjectBuffer, replaceUnderlyingArrayBuffer, sizeOf as unreliable_sizeOf, memoryStats, disposeWrapperObject, updateExternalArgs } from "./internal/api";
export { createObjectBuffer, resizeObjectBuffer, getUnderlyingArrayBuffer, loadObjectBuffer, replaceUnderlyingArrayBuffer, sizeOf as unreliable_sizeOf, memoryStats, disposeWrapperObject, updateExternalArgs, } from "./internal/api";
export { acquireLock, acquireLockWait, releaseLock } from "./internal/locks";

@@ -12,0 +12,0 @@ export declare type ExternalArgs = import("./internal/interfaces").ExternalArgsApi;

{
"name": "@bnaya/objectbuffer",
"description": "Object-like api, backed by an array buffer",
"version": "0.0.0-dfae000",
"version": "0.0.0-f1ba10a",
"main": "dist/objectbuffer.cjs.js",

@@ -36,39 +36,40 @@ "module": "dist/index.js",

"webpack-playground": "webpack-dev-server --mode=development --config playground/webpack.config.js --open",
"generate-docs": "rimraf -f docs/generated/ && typedoc --out docs/generated/ --includes . --name objectbuffer --readme none --entryPoint \"\\\"index\\\"\" --excludeNotExported --ignoreCompilerErrors --mode modules src/index.ts"
"generate-docs": "rimraf -f docs/generated/ && typedoc --mode library --readme none --out docs/generated/ --excludeNotExported --ignoreCompilerErrors src/index.ts"
},
"devDependencies": {
"@babel/cli": "^7.8.4",
"@babel/core": "^7.8.4",
"@babel/preset-env": "^7.8.4",
"@babel/preset-typescript": "^7.8.3",
"@babel/core": "^7.9.0",
"@babel/preset-env": "^7.9.5",
"@babel/preset-typescript": "^7.9.0",
"@types/benchmark": "^1.0.31",
"@types/jest": "^25.1.2",
"@types/jest": "^25.2.1",
"@types/node": "^12.12.21",
"@typescript-eslint/eslint-plugin": "^2.19.0",
"@typescript-eslint/parser": "^2.19.0",
"babel-loader": "^8.0.6",
"@typescript-eslint/eslint-plugin": "^2.27.0",
"@typescript-eslint/parser": "^2.27.0",
"babel-loader": "^8.1.0",
"benchmark": "^2.1.4",
"concurrently": "^5.1.0",
"core-js": "^3.6.4",
"core-js": "^3.6.5",
"eslint": "^6.8.0",
"eslint-config-prettier": "^6.10.0",
"eslint-config-prettier": "^6.10.1",
"eslint-plugin-prettier": "^3.1.2",
"gh-pages": "^2.2.0",
"html-webpack-plugin": "^3.2.0",
"husky": "^4.2.1",
"jest": "^25.1.0",
"prettier": "^1.19.1",
"html-webpack-plugin": "^4.2.0",
"husky": "^4.2.5",
"jest": "^25.3.0",
"kind-of": "^6.0.3",
"prettier": "^2.0.4",
"prettier-eslint": "^9.0.1",
"rimraf": "^3.0.1",
"rollup": "^1.31.0",
"rollup-plugin-babel": "^4.3.3",
"rimraf": "^3.0.2",
"rollup": "^2.4.0",
"rollup-plugin-babel": "^4.4.0",
"rollup-plugin-node-resolve": "^5.2.0",
"typedoc": "^0.16.9",
"typedoc-plugin-markdown": "^2.2.16",
"typescript": "^3.7.5",
"webpack": "^4.41.5",
"webpack-cli": "^3.3.10",
"typedoc": "^0.17.0-3",
"typedoc-plugin-markdown": "^2.2.17",
"typescript": "^3.8.3",
"webpack": "^4.42.1",
"webpack-cli": "^3.3.11",
"webpack-dev-server": "^3.10.3",
"worker-loader": "^2.0.0",
"yarn-deduplicate": "^1.1.1"
"yarn-deduplicate": "^2.0.0"
},

@@ -88,4 +89,4 @@ "husky": {

"dependencies": {
"@thi.ng/malloc": "^4.1.3"
"@thi.ng/malloc": "^4.1.10"
}
}

@@ -1,2 +0,2 @@

# ObjectBuffer: object-like API, backed by a [shared]arraybuffer
# ObjectBuffer: object-like API, backed by a [shared]arraybuffer 👀

@@ -6,14 +6,17 @@ [![npm version](https://badge.fury.io/js/%40bnaya%2Fobjectbuffer.svg)](https://badge.fury.io/js/%40bnaya%2Fobjectbuffer)

## The readme is for latest release `v0.10.0`.big refactor ongoing (allocator, hashmap)
For Modern browsers and node.
For Modern browsers and node. Zero direct dependencies.
Save, read and update plain javascript objects into `ArrayBuffer` (And not only TypedArrays), using regular javascript object api, without serialization/deserialization, or pre-defined schema.
In other words, It's an implementation of javascript objects in user-land.
Save, read and update plain javascript objects into `ArrayBuffer` (And not only TypedArrays), using regular javascript object api, without serialization/deserialization.
Look at it as a simple implementation of javascript objects in user-land.
That's enables us to `transfer` or share objects in-memory with `WebWorker` without additional memory or serialization
While the library is not `1.0`, it is usable.
The library is still not `1.0`, but already usable, and will never offer full compatibility with plain js (`Symbol` and such)
A core part of the library is an allocator, that allocates & free memory on the `ArrayBuffer` for us!
The allocator in use is [@thi.ng/malloc](https://www.npmjs.com/package/@thi.ng/malloc), part of the amazing [thi.ng/umbrella](https://github.com/thi-ng/umbrella) project
For in-depth overview of how things are implemented, see [implementation details document](docs/implementationDetails.md)
## 🐉🐉🐉 Adventurers Beware 🐉🐉🐉
Using this library, and workers in general, will not necessarily make you code faster.
First be sure where are your bottlenecks and if you don't have a better and more simple workaround.
I personally also really like what's going on around the [main thread scheduling proposal](https://github.com/WICG/main-thread-scheduling) and [react userland scheduler](https://www.npmjs.com/package/scheduler) that powers concurrent react

@@ -30,7 +33,3 @@ ## Quick example

const myObject = createObjectBuffer(
{
// available globally in the browser, or inside `util` in node
textEncoder: new TextEncoder(),
textDecoder: new TextDecoder()
},
{},
// size in bytes

@@ -84,15 +83,17 @@ 1024,

* Date
* Internal references (`foo.bar2 = foo.bar` will not create a copy)
* BigInt
* Internal references (`foo.bar2 = foo.bar` will not create a copy, but a reference)
* Automatic reference counting, to dispose a value you need to use the `disposeWrapperObject` or to have WeakRef support
* Internal equality between objects (`foo.bar === foo.bar` will be true)
* global lock for shared memory using [Atomics](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Atomics) (i hope its really working)
* global lock for shared memory using [Atomics](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Atomics) (I hope its really working)
## Caveats & Limitations
* Need to specify size for the `ArrayBuffer`. When exceed that size, exception will be thrown. (Can be extended with a utility function, but not automatically)
* Not memory re-use. memory allocation is append based, or overwrite when possible [#21](https://github.com/Bnaya/objectbuffer/issues/21)
* Object are implemented using simple linked list [#26](https://github.com/Bnaya/objectbuffer/issues/26)
* Maps & Sets are not supported yet [#15](https://github.com/Bnaya/objectbuffer/issues/15) & [#24](https://github.com/Bnaya/objectbuffer/issues/24)
* No prototype chain. objects props will simply be copied
* Additional props on Array, Date, primitives will not be saved.
* getters, setters, will not work/break the library
* Need to specify size for the `ArrayBuffer`. When exceed that size, exception will be thrown. (Can be extended later with a utility function, but not automatically)
* Set, Map, Object keys can be only string or numbers. no symbols or other things
* You can't save objects with circularities (But you can create them on objectbuffer)
* No prototype chain. no methods on the objects
* Adding getters, setters, will not work/break the library
* deleting/removing the current key of Map/Set while iteration will make you skip the next key [#60](https://github.com/Bnaya/objectbuffer/issues/60)
* unreliable_sizeOf is unreliable due to hashmap array side depends on actual keys, Also It's an expensive operation

@@ -103,3 +104,3 @@ ### What's not working yet, but can be

### What's probably never going to work (convince me otherwise )
### What's probably never going to work

@@ -112,2 +113,10 @@ * Anything that cannot go into `JSON.stringify`

There's a huge place for optimizations, code hygiene, and features!
Feel free to open issues and maybe implementing missing parts
Feel free to open issues and maybe implementing missing parts.
The code is Written in TypeScript 🦾, but the semantics are more like `C` 🥵
Have a look on the [issues](https://github.com/Bnaya/objectbuffer/issues) and see if you find something interesting
## If you came this far, you better also look at:
* [GoogleChromeLabs/buffer-backed-object](https://github.com/GoogleChromeLabs/buffer-backed-object#readme)
* [FlatBuffers](https://google.github.io/flatbuffers/flatbuffers_guide_use_javascript.html)
/* eslint-env jest */
import * as util from "util";
import { createObjectBuffer } from "../";

@@ -12,5 +10,3 @@ import { memoryStats } from "../internal/api";

const externalArgs = externalArgsApiToExternalArgsApi({
textEncoder: new util.TextEncoder(),
textDecoder: new util.TextDecoder(),
arrayAdditionalAllocation: 0
arrayAdditionalAllocation: 0,
});

@@ -17,0 +13,0 @@

/* eslint-env jest */
import * as util from "util";
import { createObjectBuffer } from "../";

@@ -11,5 +9,3 @@ import { memoryStats } from "../internal/api";

const externalArgs = externalArgsApiToExternalArgsApi({
textEncoder: new util.TextEncoder(),
textDecoder: new util.TextDecoder(),
arrayAdditionalAllocation: 0
arrayAdditionalAllocation: 0,
});

@@ -20,3 +16,3 @@

// 1/1 2000
myDate: new Date(946684800000)
myDate: new Date(946684800000),
});

@@ -23,0 +19,0 @@

/* eslint-env jest */
import * as util from "util";
import { createObjectBuffer } from "../";

@@ -11,5 +9,3 @@ import { memoryStats } from "../internal/api";

const externalArgs = externalArgsApiToExternalArgsApi({
textEncoder: new util.TextEncoder(),
textDecoder: new util.TextDecoder(),
arrayAdditionalAllocation: 0
arrayAdditionalAllocation: 0,
});

@@ -16,0 +12,0 @@

/* eslint-env jest */
import * as util from "util";
import { createObjectBuffer } from "../";

@@ -10,6 +8,3 @@ import { memoryStats } from "../internal/api";

describe("Map", () => {
const externalArgs = externalArgsApiToExternalArgsApi({
textEncoder: new util.TextEncoder(),
textDecoder: new util.TextDecoder()
});
const externalArgs = externalArgsApiToExternalArgsApi({});

@@ -75,3 +70,6 @@ test("creation", () => {

objectBuffer.foo = new Map([[1, "a"]]);
objectBuffer.foo = new Map();
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`680`);
objectBuffer.foo.set(1, "a");
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`592`);
objectBuffer.foo.set("2", "b");

@@ -121,3 +119,3 @@ expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`504`);

[1, "a"],
[2, "b"]
[2, "b"],
]);

@@ -131,4 +129,4 @@ for (const [key] of nativeMap) {

[1, "a"],
[2, "b"]
])
[2, "b"],
]),
});

@@ -157,3 +155,3 @@ for (const [key] of objectBuffer.foo) {

expect(thisArgs.every(v => v === objectBuffer.foo)).toBe(true);
expect(thisArgs.every((v) => v === objectBuffer.foo)).toBe(true);

@@ -160,0 +158,0 @@ expect(dump).toMatchInlineSnapshot(`

/* eslint-env jest */
import * as util from "util";
import { createObjectBuffer } from "../";

@@ -11,5 +9,3 @@ import { resizeObjectBuffer, memoryStats } from "../internal/api";

const externalArgs = externalArgsApiToExternalArgsApi({
textEncoder: new util.TextEncoder(),
textDecoder: new util.TextDecoder(),
arrayAdditionalAllocation: 0
arrayAdditionalAllocation: 0,
});

@@ -20,3 +16,3 @@

arr: [1, 2, 3, 4],
obj: { a: 1 }
obj: { a: 1 },
});

@@ -35,3 +31,3 @@

arr: [1, 2, 3, 4],
obj: { a: 1 }
obj: { a: 1 },
});

@@ -38,0 +34,0 @@

/* eslint-env jest */
import * as util from "util";
import { createObjectBuffer } from "../";

@@ -10,6 +8,3 @@ import { memoryStats } from "../internal/api";

describe("object tests", () => {
const externalArgs = externalArgsApiToExternalArgsApi({
textEncoder: new util.TextEncoder(),
textDecoder: new util.TextDecoder()
});
const externalArgs = externalArgsApiToExternalArgsApi({});

@@ -36,3 +31,3 @@ test("delete object prop", () => {

e: undefined,
foo: { a: 1, b: true, c: false, d: null, e: undefined }
foo: { a: 1, b: true, c: false, d: null, e: undefined },
};

@@ -60,2 +55,28 @@

});
// Not working. will make infinite loop
test.skip("With circular", () => {
const input: any = {
a: 1,
b: true,
c: false,
d: null,
e: undefined,
foo: { a: 1, b: true, c: false, d: null, e: undefined },
};
// Create circularity
input.foo.circular = input.foo;
const objectBuffer = createObjectBuffer<any>(externalArgs, 2048, input);
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`1016`);
expect(input).toEqual(objectBuffer);
expect(objectBuffer.foo.circular).toEqual(objectBuffer.foo);
expect(objectBuffer.foo.circular.d).toMatchInlineSnapshot();
objectBuffer.foo.circular = "severe the circularity";
expect(objectBuffer).toMatchInlineSnapshot();
});
});
/* eslint-env jest */
import * as util from "util";
import { createObjectBuffer, resizeObjectBuffer } from "../";

@@ -9,7 +7,7 @@ import {

replaceUnderlyingArrayBuffer,
memoryStats
memoryStats,
} from "../internal/api";
import {
arrayBufferCopyTo,
externalArgsApiToExternalArgsApi
externalArgsApiToExternalArgsApi,
} from "../internal/utils";

@@ -19,5 +17,3 @@

const externalArgs = externalArgsApiToExternalArgsApi({
textEncoder: new util.TextEncoder(),
textDecoder: new util.TextDecoder(),
arrayAdditionalAllocation: 0
arrayAdditionalAllocation: 0,
});

@@ -27,3 +23,3 @@

const objectBuffer = createObjectBuffer<any>(externalArgs, 512, {
a: 1
a: 1,
});

@@ -52,3 +48,3 @@

const objectBuffer = createObjectBuffer<any>(externalArgs, 1024, {
obj1: { a: 1 }
obj1: { a: 1 },
});

@@ -55,0 +51,0 @@

/* eslint-env jest */
import * as util from "util";
import { createObjectBuffer } from "../";

@@ -12,5 +10,3 @@ import { memoryStats } from "../internal/api";

const externalArgs = externalArgsApiToExternalArgsApi({
textEncoder: new util.TextEncoder(),
textDecoder: new util.TextDecoder(),
arrayAdditionalAllocation: 0
arrayAdditionalAllocation: 0,
});

@@ -26,3 +22,3 @@

const objectBuffer = createObjectBuffer<any>(externalArgs, 312, {
value: "first value 123"
value: "first value 123",
});

@@ -29,0 +25,0 @@ const freeSpaceLeft = memoryStats(objectBuffer).available;

/* eslint-env jest */
import * as util from "util";
import { createObjectBuffer } from "../";

@@ -10,6 +8,3 @@ import { memoryStats } from "../internal/api";

describe("Set tests", () => {
const externalArgs = externalArgsApiToExternalArgsApi({
textEncoder: new util.TextEncoder(),
textDecoder: new util.TextDecoder()
});
const externalArgs = externalArgsApiToExternalArgsApi({});

@@ -125,3 +120,3 @@ test("creation", () => {

const objectBuffer = createObjectBuffer<any>(externalArgs, 1024, {
foo: new Set(["a", "b"])
foo: new Set(["a", "b"]),
});

@@ -150,3 +145,3 @@ for (const [key] of objectBuffer.foo) {

expect(thisArgs.every(v => v === objectBuffer.foo)).toBe(true);
expect(thisArgs.every((v) => v === objectBuffer.foo)).toBe(true);

@@ -153,0 +148,0 @@ expect(dump).toMatchInlineSnapshot(`

/* eslint-env jest */
import * as util from "util";
import { createObjectBuffer } from "../";

@@ -12,5 +10,3 @@ import { memoryStats, disposeWrapperObject } from "../internal/api";

const externalArgs = externalArgsApiToExternalArgsApi({
textEncoder: new util.TextEncoder(),
textDecoder: new util.TextDecoder(),
arrayAdditionalAllocation: 0
arrayAdditionalAllocation: 0,
});

@@ -17,0 +13,0 @@

/* eslint-disable */
import { ExternalArgs } from "../internal/interfaces";
import * as util from "util";
import { createObjectBuffer } from "..";

@@ -27,6 +27,6 @@ import { memoryStats } from "../internal/api";

const externalArgs = externalArgsApiToExternalArgsApi({
textEncoder: new util.TextEncoder(),
textDecoder: new util.TextDecoder(),
arrayAdditionalAllocation: 0,
});

@@ -33,0 +33,0 @@

@@ -1,2 +0,1 @@

import * as util from "util";
import { createObjectBuffer } from "..";

@@ -10,5 +9,3 @@ import { memoryStats } from "../internal/api";

const externalArgs = externalArgsApiToExternalArgsApi({
textEncoder: new util.TextEncoder(),
textDecoder: new util.TextDecoder(),
arrayAdditionalAllocation: 0
arrayAdditionalAllocation: 0,
});

@@ -18,3 +15,3 @@

const objectBuffer = createObjectBuffer<any>(externalArgs, 256, {
foo: null
foo: null,
});

@@ -30,3 +27,3 @@

more: "than size",
arr: [1, 2, 3]
arr: [1, 2, 3],
};

@@ -33,0 +30,0 @@ }).toThrowErrorMatchingInlineSnapshot(`"OutOfMemoryError"`);

@@ -1,2 +0,1 @@

import * as util from "util";
import { createObjectBuffer } from "..";

@@ -10,5 +9,3 @@ import { memoryStats } from "../internal/api";

const externalArgs = externalArgsApiToExternalArgsApi({
textEncoder: new util.TextEncoder(),
textDecoder: new util.TextDecoder(),
arrayAdditionalAllocation: 0
arrayAdditionalAllocation: 0,
});

@@ -18,3 +15,3 @@

const objectBuffer = createObjectBuffer(externalArgs, 128, {
num: 1 as number | bigint
num: 1 as number | bigint,
});

@@ -54,3 +51,3 @@

const objectBuffer = createObjectBuffer(externalArgs, 128, {
nullContainer: null as null | undefined
nullContainer: null as null | undefined,
});

@@ -83,3 +80,3 @@

const objectBuffer = createObjectBuffer(externalArgs, 128, {
booleanContainer: false
booleanContainer: false,
});

@@ -86,0 +83,0 @@

/* eslint-env jest */
import * as util from "util";

@@ -7,3 +6,3 @@ import {

getUnderlyingArrayBuffer,
loadObjectBuffer
loadObjectBuffer,
} from ".";

@@ -15,5 +14,3 @@ import { arrayBuffer2HexArray } from "./internal/testUtils";

const externalArgs = externalArgsApiToExternalArgsApi({
textEncoder: new util.TextEncoder(),
textDecoder: new util.TextDecoder(),
arrayAdditionalAllocation: 0
arrayAdditionalAllocation: 0,
});

@@ -25,3 +22,3 @@

b: null,
c: { t: 5 }
c: { t: 5 },
});

@@ -43,5 +40,3 @@

const externalArgs = externalArgsApiToExternalArgsApi({
textEncoder: new util.TextEncoder(),
textDecoder: new util.TextDecoder(),
arrayAdditionalAllocation: 0
arrayAdditionalAllocation: 0,
});

@@ -51,3 +46,3 @@ test("getUnderlyingArrayBuffer simple", () => {

b: null,
c: { t: 5 }
c: { t: 5 },
});

@@ -66,5 +61,3 @@

const externalArgs = externalArgsApiToExternalArgsApi({
textEncoder: new util.TextEncoder(),
textDecoder: new util.TextDecoder(),
arrayAdditionalAllocation: 0
arrayAdditionalAllocation: 0,
});

@@ -76,3 +69,3 @@

b: null,
c: { t: 5 }
c: { t: 5 },
});

@@ -79,0 +72,0 @@

@@ -20,3 +20,3 @@ /**

disposeWrapperObject,
updateExternalArgs
updateExternalArgs,
} from "./internal/api";

@@ -23,0 +23,0 @@ export { acquireLock, acquireLockWait, releaseLock } from "./internal/locks";

@@ -8,3 +8,4 @@ import { initializeArrayBuffer } from "./store";

externalArgsApiToExternalArgsApi,
getInternalAPI
getInternalAPI,
isPrimitive,
} from "./utils";

@@ -14,2 +15,3 @@ import { getCacheFor } from "./externalObjectsCache";

import { MemPool } from "@thi.ng/malloc";
import { UnsupportedOperationError } from "./exceptions";

@@ -37,2 +39,12 @@ export interface CreateObjectBufferOptions {

): T {
if (
Array.isArray(initialValue) ||
initialValue instanceof Date ||
initialValue instanceof Map ||
initialValue instanceof Set ||
isPrimitive(initialValue)
) {
throw new UnsupportedOperationError();
}
const arrayBuffer = new (options.useSharedArrayBuffer

@@ -46,3 +58,3 @@ ? SharedArrayBuffer

buf: arrayBuffer,
start: MEM_POOL_START
start: MEM_POOL_START,
});

@@ -57,3 +69,3 @@

float64: new Float64Array(arrayBuffer),
bigUint64: new BigUint64Array(arrayBuffer)
bigUint64: new BigUint64Array(arrayBuffer),
};

@@ -65,2 +77,3 @@

[],
new Map(),
initialValue

@@ -127,3 +140,3 @@ );

start: MEM_POOL_START,
skipInitialization: true
skipInitialization: true,
});

@@ -138,3 +151,3 @@

float64: new Float64Array(arrayBuffer),
bigUint64: new BigUint64Array(arrayBuffer)
bigUint64: new BigUint64Array(arrayBuffer),
};

@@ -179,3 +192,3 @@

start: MEM_POOL_START,
skipInitialization: true
skipInitialization: true,
});

@@ -190,3 +203,3 @@

float64: new Float64Array(newArrayBuffer),
bigUint64: new BigUint64Array(newArrayBuffer)
bigUint64: new BigUint64Array(newArrayBuffer),
};

@@ -213,3 +226,3 @@

skipInitialization: true,
start: MEM_POOL_START
start: MEM_POOL_START,
});

@@ -216,0 +229,0 @@

/* eslint-env jest */
import { initializeArrayBuffer } from "./store";
import * as util from "util";
import { arraySaver } from "./arraySaver";

@@ -9,3 +9,3 @@ import {

getFinalValueAtArrayIndex,
setValueAtArrayIndex
setValueAtArrayIndex,
} from "./arrayHelpers";

@@ -19,5 +19,3 @@ import { ExternalArgs } from "./interfaces";

const externalArgs: ExternalArgs = externalArgsApiToExternalArgsApi({
textEncoder: new util.TextEncoder(),
textDecoder: new util.TextDecoder(),
arrayAdditionalAllocation: 0
arrayAdditionalAllocation: 0,
});

@@ -58,3 +56,3 @@

buf: arrayBuffer,
start: MEM_POOL_START
start: MEM_POOL_START,
});

@@ -84,3 +82,3 @@

buf: arrayBuffer,
start: MEM_POOL_START
start: MEM_POOL_START,
});

@@ -110,3 +108,3 @@

buf: arrayBuffer,
start: MEM_POOL_START
start: MEM_POOL_START,
});

@@ -137,3 +135,3 @@

buf: arrayBuffer,
start: MEM_POOL_START
start: MEM_POOL_START,
});

@@ -140,0 +138,0 @@

import {
readEntry,
writeEntry,
writeValueInPtrToPtrAndHandleMemory
writeValueInPtrToPtrAndHandleMemory,
} from "./store";

@@ -40,3 +40,3 @@ import { ArrayEntry, ExternalArgs, GlobalCarrier } from "./interfaces";

pointer,
pointerToThePointer
pointerToThePointer,
};

@@ -47,3 +47,3 @@ }

externalArgs: ExternalArgs,
dataViewCarrier: GlobalCarrier,
globalCarrier: GlobalCarrier,
pointerToArrayEntry: number,

@@ -53,3 +53,3 @@ indexToGet: number

const pointers = arrayGetPointersToValueInIndex(
dataViewCarrier,
globalCarrier,
pointerToArrayEntry,

@@ -65,3 +65,3 @@ indexToGet

externalArgs,
dataViewCarrier,
globalCarrier,
pointers.pointer

@@ -138,3 +138,3 @@ );

allocatedLength: metadata.allocatedLength,
length: wishedLength
length: wishedLength,
});

@@ -161,3 +161,3 @@ }

allocatedLength: metadata.allocatedLength,
length: wishedLength
length: wishedLength,
});

@@ -198,3 +198,3 @@ }

allocatedLength: newAllocatedLength,
length: newLength
length: newLength,
});

@@ -205,18 +205,18 @@ }

externalArgs: ExternalArgs,
dataViewCarrier: GlobalCarrier,
globalCarrier: GlobalCarrier,
pointerToArrayEntry: number,
sortComparator: (a: any, b: any) => 1 | -1 | 0 = defaultCompareFunction
) {
const metadata = arrayGetMetadata(dataViewCarrier, pointerToArrayEntry);
const metadata = arrayGetMetadata(globalCarrier, pointerToArrayEntry);
const pointersToValues = [...new Array(metadata.length).keys()]
.map(index => metadata.value + index * Uint32Array.BYTES_PER_ELEMENT)
.map((index) => metadata.value + index * Uint32Array.BYTES_PER_ELEMENT)
.map(
pointerToPointer =>
dataViewCarrier.uint32[pointerToPointer / Uint32Array.BYTES_PER_ELEMENT]
(pointerToPointer) =>
globalCarrier.uint32[pointerToPointer / Uint32Array.BYTES_PER_ELEMENT]
);
const sortMe = pointersToValues.map(pointer => {
const sortMe = pointersToValues.map((pointer) => {
return [
pointer,
entryToFinalJavaScriptValue(externalArgs, dataViewCarrier, pointer)
entryToFinalJavaScriptValue(externalArgs, globalCarrier, pointer),
] as const;

@@ -230,3 +230,3 @@ });

for (let i = 0; i < sortMe.length; i += 1) {
dataViewCarrier.uint32[
globalCarrier.uint32[
(metadata.value + i * Uint32Array.BYTES_PER_ELEMENT) /

@@ -233,0 +233,0 @@ Uint32Array.BYTES_PER_ELEMENT

/* eslint-env jest */
import { initializeArrayBuffer } from "./store";
import * as util from "util";
import { arrayBuffer2HexArray, makeCarrier } from "./testUtils";

@@ -11,5 +11,3 @@ import { arraySaver } from "./arraySaver";

const externalArgs = externalArgsApiToExternalArgsApi({
textEncoder: new util.TextEncoder(),
textDecoder: new util.TextDecoder(),
arrayAdditionalAllocation: 20
arrayAdditionalAllocation: 20,
});

@@ -16,0 +14,0 @@

@@ -23,7 +23,13 @@ import { appendEntry } from "./store";

arrayToSave.length + externalArgs.arrayAdditionalAllocation,
length: arrayToSave.length
length: arrayToSave.length,
};
for (const item of arrayToSave) {
const rOfValue = saveValue(externalArgs, carrier, referencedPointers, item);
const rOfValue = saveValue(
externalArgs,
carrier,
referencedPointers,
new Map(),
item
);

@@ -30,0 +36,0 @@ carrier.uint32[

/* eslint-env jest */
import { initializeArrayBuffer } from "./store";
import * as util from "util";
import { createArrayWrapper } from "./arrayWrapper";

@@ -14,5 +14,3 @@ import { arraySaver } from "./arraySaver";

const externalArgs = externalArgsApiToExternalArgsApi({
textEncoder: new util.TextEncoder(),
textDecoder: new util.TextDecoder(),
arrayAdditionalAllocation: 20
arrayAdditionalAllocation: 20,
});

@@ -26,3 +24,3 @@

buf: arrayBuffer,
start: MEM_POOL_START
start: MEM_POOL_START,
});

@@ -100,3 +98,3 @@

buf: arrayBuffer,
start: MEM_POOL_START
start: MEM_POOL_START,
});

@@ -151,3 +149,3 @@

buf: arrayBuffer,
start: MEM_POOL_START
start: MEM_POOL_START,
});

@@ -211,3 +209,3 @@

buf: arrayBuffer,
start: MEM_POOL_START
start: MEM_POOL_START,
});

@@ -293,3 +291,3 @@

buf: arrayBuffer,
start: MEM_POOL_START
start: MEM_POOL_START,
});

@@ -376,3 +374,3 @@

buf: arrayBuffer,
start: MEM_POOL_START
start: MEM_POOL_START,
});

@@ -445,3 +443,3 @@

buf: arrayBuffer,
start: MEM_POOL_START
start: MEM_POOL_START,
});

@@ -520,3 +518,3 @@

buf: arrayBuffer,
start: MEM_POOL_START
start: MEM_POOL_START,
});

@@ -595,3 +593,3 @@

buf: arrayBuffer,
start: MEM_POOL_START
start: MEM_POOL_START,
});

@@ -598,0 +596,0 @@

@@ -7,3 +7,3 @@ import {

arrayGetPointersToValueInIndex,
setValuePointerAtArrayIndex
setValuePointerAtArrayIndex,
} from "./arrayHelpers";

@@ -17,3 +17,3 @@ import { assertNonNull } from "./assertNonNull";

externalArgs: ExternalArgs,
dataViewCarrier: GlobalCarrier,
globalCarrier: GlobalCarrier,
pointerToArrayEntry: number,

@@ -24,3 +24,3 @@ startArg: number,

) {
const metadata = arrayGetMetadata(dataViewCarrier, pointerToArrayEntry);
const metadata = arrayGetMetadata(globalCarrier, pointerToArrayEntry);

@@ -39,3 +39,3 @@ const calcedStart = calculateSpliceStart(metadata.length, startArg);

externalArgs,
dataViewCarrier,
globalCarrier,
pointerToArrayEntry,

@@ -57,3 +57,3 @@ newLength

externalArgs,
dataViewCarrier,
globalCarrier,
pointerToArrayEntry,

@@ -78,3 +78,3 @@ deletedItemIndexToSave

const valueToCopyPointers = arrayGetPointersToValueInIndex(
dataViewCarrier,
globalCarrier,
pointerToArrayEntry,

@@ -87,3 +87,3 @@ writeValueToIndex - itemCountChange

setValuePointerAtArrayIndex(
dataViewCarrier,
globalCarrier,
pointerToArrayEntry,

@@ -94,3 +94,3 @@ writeValueToIndex,

dataViewCarrier.uint32[
globalCarrier.uint32[
valueToCopyPointers.pointerToThePointer / Uint32Array.BYTES_PER_ELEMENT

@@ -113,3 +113,3 @@ ] = 0;

const valueToCopyPointers = arrayGetPointersToValueInIndex(
dataViewCarrier,
globalCarrier,
pointerToArrayEntry,

@@ -122,3 +122,3 @@ writeValueToIndex - itemCountChange

setValuePointerAtArrayIndex(
dataViewCarrier,
globalCarrier,
pointerToArrayEntry,

@@ -131,3 +131,3 @@ writeValueToIndex,

dataViewCarrier.uint32[
globalCarrier.uint32[
valueToCopyPointers.pointerToThePointer / Uint32Array.BYTES_PER_ELEMENT

@@ -151,3 +151,3 @@ ] = 0;

const valueToSetPointers = arrayGetPointersToValueInIndex(
dataViewCarrier,
globalCarrier,
pointerToArrayEntry,

@@ -161,3 +161,3 @@ calcedStart + i

externalArgs,
dataViewCarrier,
globalCarrier,
valueToSetPointers.pointerToThePointer,

@@ -169,3 +169,3 @@ itemsToAddArg[i]

if (newLength < metadata.length) {
shrinkArray(externalArgs, dataViewCarrier, pointerToArrayEntry, newLength);
shrinkArray(externalArgs, globalCarrier, pointerToArrayEntry, newLength);
}

@@ -172,0 +172,0 @@

/* eslint-env jest */
import { initializeArrayBuffer } from "./store";
import * as util from "util";
import { createArrayWrapper } from "./arrayWrapper";

@@ -14,5 +14,3 @@ import { arraySaver } from "./arraySaver";

const externalArgs = externalArgsApiToExternalArgsApi({
textEncoder: new util.TextEncoder(),
textDecoder: new util.TextDecoder(),
arrayAdditionalAllocation: 20
arrayAdditionalAllocation: 20,
});

@@ -27,3 +25,3 @@

buf: arrayBuffer,
start: MEM_POOL_START
start: MEM_POOL_START,
});

@@ -58,3 +56,3 @@

buf: arrayBuffer,
start: MEM_POOL_START
start: MEM_POOL_START,
});

@@ -82,3 +80,3 @@ const arrayToSave = ["a", "b", 1];

buf: arrayBuffer,
start: MEM_POOL_START
start: MEM_POOL_START,
});

@@ -121,3 +119,3 @@ const arrayToSave = ["a", "b", 1];

buf: arrayBuffer,
start: MEM_POOL_START
start: MEM_POOL_START,
});

@@ -221,3 +219,3 @@ const arrayToSave = ["a", "b", 1];

buf: arrayBuffer,
start: MEM_POOL_START
start: MEM_POOL_START,
});

@@ -261,3 +259,3 @@ const arrayToSave = ["a", "b", 1];

buf: arrayBuffer,
start: MEM_POOL_START
start: MEM_POOL_START,
});

@@ -299,7 +297,7 @@

buf: arrayBuffer,
start: MEM_POOL_START
start: MEM_POOL_START,
});
const arrayToSave = [2, 1, 3, 10, 6, 77].map(value => ({
value
const arrayToSave = [2, 1, 3, 10, 6, 77].map((value) => ({
value,
}));

@@ -357,3 +355,3 @@

buf: arrayBuffer,
start: MEM_POOL_START
start: MEM_POOL_START,
});

@@ -398,3 +396,3 @@

buf: arrayBuffer,
start: MEM_POOL_START
start: MEM_POOL_START,
});

@@ -401,0 +399,0 @@

@@ -7,3 +7,3 @@ import {

extendArrayIfNeeded,
arrayReverse
arrayReverse,
} from "./arrayHelpers";

@@ -15,3 +15,3 @@ import { INTERNAL_API_SYMBOL } from "./symbols";

IllegalArrayIndexError,
UnsupportedOperationError
UnsupportedOperationError,
} from "./exceptions";

@@ -173,3 +173,3 @@ import { allocationsTransaction } from "./allocationsTransaction";

index
)
),
];

@@ -294,3 +294,3 @@

externalArgs: ExternalArgs,
dataViewCarrier: GlobalCarrier,
globalCarrier: GlobalCarrier,
entryPointer: number

@@ -300,4 +300,4 @@ ): Array<any> {

[],
new ArrayWrapper(externalArgs, dataViewCarrier, entryPointer)
new ArrayWrapper(externalArgs, globalCarrier, entryPointer)
) as any;
}

@@ -9,3 +9,3 @@ import {

MapEntry,
SetEntry
SetEntry,
} from "./interfaces";

@@ -12,0 +12,0 @@ import { incrementRefCount, decrementRefCount, readEntry } from "./store";

@@ -38,3 +38,3 @@ import { ExternalArgs, GlobalCarrier, DateEntry } from "./interfaces";

"toLocaleDateString",
"toLocaleTimeString"
"toLocaleTimeString",
];

@@ -58,3 +58,3 @@

"setUTCMonth",
"setUTCSeconds"
"setUTCSeconds",
// "setYear"

@@ -118,3 +118,3 @@ ];

refsCount: this.entry.refsCount,
value: this.dateObjectForReuse.getTime()
value: this.dateObjectForReuse.getTime(),
});

@@ -121,0 +121,0 @@ }

@@ -1,2 +0,1 @@

import * as util from "util";
import { createObjectBuffer } from "..";

@@ -9,5 +8,3 @@ import { externalArgsApiToExternalArgsApi } from "./utils";

const externalArgs = externalArgsApiToExternalArgsApi({
textEncoder: new util.TextEncoder(),
textDecoder: new util.TextDecoder(),
arrayAdditionalAllocation: 20
arrayAdditionalAllocation: 20,
});

@@ -19,3 +16,3 @@

array: [1],
object: {}
object: {},
});

@@ -35,3 +32,3 @@

Object.defineProperty(objectBuffer.date, "propy", {
enumerable: true
enumerable: true,
});

@@ -59,3 +56,3 @@ }).toThrowErrorMatchingInlineSnapshot(`"UnsupportedOperationError"`);

array: [1],
object: {}
object: {},
});

@@ -92,3 +89,3 @@

array: [1],
object: {}
object: {},
});

@@ -99,3 +96,3 @@

configurable: false,
enumerable: false
enumerable: false,
});

@@ -102,0 +99,0 @@ }).toThrowErrorMatchingInlineSnapshot(`"UnsupportedOperationError"`);

@@ -29,3 +29,3 @@ import { createKnownTypeGuard } from "./utils";

SET,
DATE
DATE,
}

@@ -37,5 +37,5 @@

ENTRY_TYPE.BIGINT_NEGATIVE,
ENTRY_TYPE.STRING
ENTRY_TYPE.STRING,
] as const;
export const isPrimitiveEntryType = createKnownTypeGuard(PRIMITIVE_TYPES);

@@ -15,3 +15,3 @@ import { ExternalArgs, GlobalCarrier } from "./interfaces";

TRUE_KNOWN_ADDRESS,
FALSE_KNOWN_ADDRESS
FALSE_KNOWN_ADDRESS,
} from "./consts";

@@ -27,3 +27,3 @@

[ENTRY_TYPE.MAP]: createMapWrapper,
[ENTRY_TYPE.SET]: createSetWrapper
[ENTRY_TYPE.SET]: createSetWrapper,
} as const;

@@ -65,3 +65,3 @@

) {
const cache = getCacheFor(carrier, key => {
const cache = getCacheFor(carrier, (key) => {
finalizer(key, carrier, externalArgs);

@@ -68,0 +68,0 @@ });

@@ -26,3 +26,7 @@ import { WeakValueMap } from "./WeakValueMap";

function supportWeakRef() {
return typeof WeakRef !== "undefined";
return (
typeof WeakRef !== "undefined" &&
(typeof FinalizationGroup !== "undefined" ||
typeof "FinalizationRegistry" !== "undefined")
);
}
/* eslint-env jest */
import * as util from "util";
import { MemPool } from "@thi.ng/malloc";

@@ -11,9 +10,7 @@ import { createObjectBuffer, memoryStats } from "./api";

const externalArgs = externalArgsApiToExternalArgsApi({
textEncoder: new util.TextEncoder(),
textDecoder: new util.TextDecoder(),
arrayAdditionalAllocation: 20
arrayAdditionalAllocation: 20,
});
describe("getAllLinkedAddresses no reference counting", () => {
test("getAllLinkedAddresses", () => {
describe("Make sure all allocated are discovered", () => {
test("Small object", () => {
const allocatedAddresses: number[] = [];

@@ -30,4 +27,74 @@ const origMalloc = MemPool.prototype.malloc;

const objectBuffer = createObjectBuffer(externalArgs, 2048, {
smallObject: [{ a: "6" }],
});
// const a = objectBuffer.nestedObject;
// getInternalAPI(a).destroy();
// // a.toString();
const carrier = getInternalAPI(objectBuffer).getCarrier();
const entryPointer = getInternalAPI(objectBuffer).getEntryPointer();
getInternalAPI(objectBuffer).destroy();
const linkedAddresses = getAllLinkedAddresses(
carrier,
false,
// allocatedAddresses[allocatedAddresses.length - 1]
entryPointer
);
expect([...linkedAddresses.leafAddresses].slice().sort()).toEqual(
allocatedAddresses.slice().sort()
);
});
test("With Map & Set", () => {
const allocatedAddresses: number[] = [];
const origMalloc = MemPool.prototype.malloc;
MemPool.prototype.malloc = function malloc(dataSize: number) {
const address = origMalloc.call(this, dataSize);
allocatedAddresses.push(address);
return address;
};
const objectBuffer = createObjectBuffer(externalArgs, 2048, {
m: new Map([
["a", 1],
["b", 2],
]),
s: new Set(["a", "b", "c"]),
});
const carrier = getInternalAPI(objectBuffer).getCarrier();
const entryPointer = getInternalAPI(objectBuffer).getEntryPointer();
getInternalAPI(objectBuffer).destroy();
const linkedAddresses = getAllLinkedAddresses(
carrier,
false,
entryPointer
);
expect([...linkedAddresses.leafAddresses].slice().sort()).toEqual(
allocatedAddresses.slice().sort()
);
});
test("object with more stuff", () => {
const allocatedAddresses: number[] = [];
const origMalloc = MemPool.prototype.malloc;
MemPool.prototype.malloc = function malloc(dataSize: number) {
const address = origMalloc.call(this, dataSize);
allocatedAddresses.push(address);
return address;
};
const objectBuffer = createObjectBuffer(externalArgs, 2048, {
nestedObject: { a: 1, b: null, c: "string", bigint: BigInt("100") },
arr: [new Date(0), "somestring", { a: "6", h: null }]
arr: [new Date(0), "somestring", { a: "6", h: null }],
});

@@ -49,7 +116,7 @@

expect(linkedAddresses.leafAddresses.slice().sort()).toEqual(
expect([...linkedAddresses.leafAddresses].slice().sort()).toEqual(
allocatedAddresses.slice().sort()
);
expect(linkedAddresses.leafAddresses.slice().sort())
expect([...linkedAddresses.leafAddresses].slice().sort())
.toMatchInlineSnapshot(`

@@ -123,3 +190,3 @@ Array [

nestedObject: { a: 1, b: null, c: "string", bigint: BigInt("100") },
arr: [new Date(0), "somestring", { a: "6", h: null }]
arr: [new Date(0), "somestring", { a: "6", h: null }],
});

@@ -144,3 +211,3 @@

linkedAddresses.leafAddresses.forEach(address => {
linkedAddresses.leafAddresses.forEach((address) => {
pool.free(address);

@@ -147,0 +214,0 @@ });

@@ -12,13 +12,31 @@ import { readEntry } from "./store";

) {
const leafAddresses: number[] = [];
const arcAddresses: number[] = [];
const leafAddresses: Set<number> = new Set<number>();
const arcAddresses: Set<number> = new Set<number>();
const addressesToProcessQueue: number[] = [entryPointer];
getAllLinkedAddressesStep(
carrier,
ignoreRefCount,
entryPointer,
leafAddresses,
arcAddresses
);
let addressToProcess: number | undefined = undefined;
// const diffs = [];
while ((addressToProcess = addressesToProcessQueue.shift()) !== undefined) {
// const before = addressesToProcessQueue.slice();
if (addressToProcess === 0) {
continue;
}
getAllLinkedAddressesStep(
carrier,
ignoreRefCount,
addressToProcess,
leafAddresses,
arcAddresses,
addressesToProcessQueue
);
// diffs.push(addressesToProcessQueue.filter((p) => !before.includes(p)));
}
// console.log(diffs);
return { leafAddresses, arcAddresses };

@@ -31,6 +49,11 @@ }

entryPointer: number,
leafAddresses: number[],
arcAddresses: number[]
leafAddresses: Set<number>,
arcAddresses: Set<number>,
addressesToProcessQueue: number[]
) {
if (isKnownAddressValuePointer(entryPointer)) {
if (
isKnownAddressValuePointer(entryPointer) ||
leafAddresses.has(entryPointer) ||
arcAddresses.has(entryPointer)
) {
return;

@@ -46,3 +69,3 @@ }

case ENTRY_TYPE.BIGINT_POSITIVE:
leafAddresses.push(entryPointer);
leafAddresses.add(entryPointer);
break;

@@ -54,12 +77,11 @@

if (entry.refsCount <= 1 || ignoreRefCount) {
leafAddresses.push(entryPointer);
leafAddresses.add(entryPointer);
getObjectOrMapOrSetAddresses(
carrier,
ignoreRefCount,
entry.value,
leafAddresses,
arcAddresses
addressesToProcessQueue
);
} else {
arcAddresses.push(entryPointer);
arcAddresses.add(entryPointer);
}

@@ -71,4 +93,4 @@

if (entry.refsCount <= 1 || ignoreRefCount) {
leafAddresses.push(entryPointer);
leafAddresses.push(entry.value);
leafAddresses.add(entryPointer);
leafAddresses.add(entry.value);

@@ -82,12 +104,6 @@ for (let i = 0; i < entry.allocatedLength; i += 1) {

getAllLinkedAddressesStep(
carrier,
ignoreRefCount,
valuePointer,
leafAddresses,
arcAddresses
);
addressesToProcessQueue.push(valuePointer);
}
} else {
arcAddresses.push(entryPointer);
arcAddresses.add(entryPointer);
}

@@ -98,5 +114,5 @@ break;

if (entry.refsCount <= 1 || ignoreRefCount) {
leafAddresses.push(entryPointer);
leafAddresses.add(entryPointer);
} else {
arcAddresses.push(entryPointer);
arcAddresses.add(entryPointer);
}

@@ -114,6 +130,5 @@ break;

carrier: GlobalCarrier,
ignoreRefCount: boolean,
internalHashmapPointer: number,
leafAddresses: number[],
arcAddresses: number[]
leafAddresses: Set<number>,
addressesToProcessQueue: number[]
) {

@@ -125,13 +140,11 @@ const { pointersToValuePointers, pointers } = hashMapGetPointersToFree(

leafAddresses.push(...pointers);
for (const leafPointer of pointers) {
leafAddresses.add(leafPointer);
}
for (const pointer of pointersToValuePointers) {
getAllLinkedAddressesStep(
carrier,
ignoreRefCount,
carrier.uint32[pointer / Uint32Array.BYTES_PER_ELEMENT],
leafAddresses,
arcAddresses
addressesToProcessQueue.push(
carrier.uint32[pointer / Uint32Array.BYTES_PER_ELEMENT]
);
}
}
/* eslint-env jest */
import * as util from "util";
import {
arrayBuffer2HexArray,
recordAllocations,
makeCarrier
makeCarrier,
} from "../testUtils";

@@ -16,3 +16,3 @@ import {

hashMapDelete,
hashMapGetPointersToFree
hashMapGetPointersToFree,
} from "./hashmap";

@@ -25,5 +25,3 @@ import { GlobalCarrier, StringEntry } from "../interfaces";

const externalArgs = externalArgsApiToExternalArgsApi({
textEncoder: new util.TextEncoder(),
textDecoder: new util.TextDecoder(),
arrayAdditionalAllocation: 20
arrayAdditionalAllocation: 20,
});

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

.map((i): number => i + "a".charCodeAt(0))
.map(n => String.fromCharCode(n));
.map((n) => String.fromCharCode(n));

@@ -187,3 +185,3 @@ const inserts: number[] = [];

expect(
values.map(v => (readEntry(carrier, v.keyPointer) as StringEntry).value)
values.map((v) => (readEntry(carrier, v.keyPointer) as StringEntry).value)
).toMatchInlineSnapshot(`

@@ -230,3 +228,3 @@ Array [

.map((i): number => i + "a".charCodeAt(0))
.map(n => String.fromCharCode(n));
.map((n) => String.fromCharCode(n));

@@ -291,3 +289,3 @@ for (const [index, useThatAsKey] of input.entries()) {

.map((i): number => i + "a".charCodeAt(0))
.map(n => String.fromCharCode(n));
.map((n) => String.fromCharCode(n));
const inputCopy = input.slice();

@@ -368,3 +366,3 @@

r.pointersToValuePointers
.map(v =>
.map((v) =>
String.fromCharCode(carrier.uint32[v / Uint32Array.BYTES_PER_ELEMENT])

@@ -371,0 +369,0 @@ )

@@ -6,3 +6,3 @@ import { MAP_MACHINE, NODE_MACHINE } from "./memoryLayout";

NumberEntry,
StringEntry
StringEntry,
} from "../interfaces";

@@ -12,3 +12,3 @@ import {

hashCodeExternalValue,
getKeyStartLength
getKeyStartLength,
} from "./hashmapUtils";

@@ -20,3 +20,3 @@ import { primitiveValueToEntry } from "../utils";

readEntry,
compareStringOrNumberEntriesInPlace
compareStringOrNumberEntriesInPlace,
} from "../store";

@@ -30,3 +30,3 @@ import { ENTRY_TYPE } from "../entry-types";

linkedListGetValue,
linkedListGetPointersToFree
linkedListGetPointersToFree,
} from "../linkedList/linkedList";

@@ -321,3 +321,3 @@

valuePointer: operator.pointerTo("VALUE_POINTER"),
keyPointer: operator.get("KEY_POINTER")
keyPointer: operator.get("KEY_POINTER"),
};

@@ -357,3 +357,3 @@ }

pointers,
pointersToValuePointers
pointersToValuePointers,
};

@@ -360,0 +360,0 @@ }

@@ -67,3 +67,3 @@ import { ENTRY_TYPE } from "../entry-types";

start: keyPointer + 1,
length: Float64Array.BYTES_PER_ELEMENT
length: Float64Array.BYTES_PER_ELEMENT,
};

@@ -73,5 +73,5 @@ } else {

start: keyPointer + 1 + 2 + 2,
length: carrier.uint16[(keyPointer + 1) / Uint16Array.BYTES_PER_ELEMENT]
length: carrier.uint16[(keyPointer + 1) / Uint16Array.BYTES_PER_ELEMENT],
};
}
}

@@ -9,3 +9,3 @@ import { createMemoryMachine } from "../memoryMachinery";

CAPACITY: Uint8Array,
USED_CAPACITY: Uint8Array
USED_CAPACITY: Uint8Array,
});

@@ -17,3 +17,3 @@

KEY_POINTER: Uint32Array,
LINKED_LIST_ITEM_POINTER: Uint32Array
LINKED_LIST_ITEM_POINTER: Uint32Array,
});

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

import { ENTRY_TYPE } from "./entry-types";
import { TextDecoder, TextEncoder } from "./textEncoderDecoderTypes";

@@ -97,5 +96,7 @@ export type primitive = string | number | bigint | boolean | undefined | null;

hashMapMinInitialCapacity: number;
/**
* Allocate additional memory for array pointers,
* will prevent the reallocation and copy when array is getting bigger
*/
arrayAdditionalAllocation: number;
textDecoder: TextDecoder;
textEncoder: TextEncoder;
}>;

@@ -107,4 +108,2 @@

arrayAdditionalAllocation?: number;
textDecoder: TextDecoder;
textEncoder: TextEncoder;
}>;

@@ -111,0 +110,0 @@

@@ -6,3 +6,3 @@ /* eslint-env jest */

recordAllocations,
makeCarrier
makeCarrier,
} from "../testUtils";

@@ -20,3 +20,3 @@

linkedListGetValue,
linkedListGetPointersToFree
linkedListGetPointersToFree,
// LINKED_LIST_ITEM_MACHINE

@@ -104,3 +104,3 @@ } from "./linkedList";

linkedListItemInsert(carrier, linkedListPointer, 5),
linkedListItemInsert(carrier, linkedListPointer, 4)
linkedListItemInsert(carrier, linkedListPointer, 4),
];

@@ -132,3 +132,3 @@

itemsPointers.forEach(p => linkedListItemRemove(carrier, p));
itemsPointers.forEach((p) => linkedListItemRemove(carrier, p));

@@ -148,3 +148,3 @@ expect(carrier.allocator.stats().available).toMatchInlineSnapshot(`184`);

linkedListItemInsert(carrier, linkedListPointer, 5),
linkedListItemInsert(carrier, linkedListPointer, 4)
linkedListItemInsert(carrier, linkedListPointer, 4),
];

@@ -183,3 +183,3 @@

itemsPointers.forEach(p => linkedListItemRemove(carrier, p));
itemsPointers.forEach((p) => linkedListItemRemove(carrier, p));

@@ -200,3 +200,3 @@ expect(carrier.allocator.stats().available).toMatchInlineSnapshot(`184`);

linkedListItemInsert(carrier, linkedListPointer, 5),
linkedListItemInsert(carrier, linkedListPointer, 4)
linkedListItemInsert(carrier, linkedListPointer, 4),
];

@@ -242,3 +242,3 @@

itemsPointers.forEach(p => linkedListItemRemove(carrier, p));
itemsPointers.forEach((p) => linkedListItemRemove(carrier, p));

@@ -256,3 +256,3 @@ expect(carrier.allocator.stats().available).toMatchInlineSnapshot(`184`);

linkedListItemInsert(carrier, linkedListPointer, 7),
linkedListItemInsert(carrier, linkedListPointer, 6)
linkedListItemInsert(carrier, linkedListPointer, 6),
];

@@ -302,3 +302,3 @@

itemsPointers.forEach(p => linkedListItemRemove(carrier, p));
itemsPointers.forEach((p) => linkedListItemRemove(carrier, p));

@@ -305,0 +305,0 @@ const iteratorPointerToFree = 0;

@@ -21,3 +21,3 @@ import { createMemoryMachine } from "../memoryMachinery";

NEXT_POINTER: Uint32Array,
VALUE: Uint32Array
VALUE: Uint32Array,
});

@@ -31,3 +31,3 @@

END_POINTER: Uint32Array,
START_POINTER: Uint32Array
START_POINTER: Uint32Array,
});

@@ -202,4 +202,4 @@ export type LinkedListMachineType = ReturnType<

pointers,
valuePointers
valuePointers,
};
}

@@ -5,3 +5,3 @@ import {

MapEntry,
InternalAPI
InternalAPI,
} from "./interfaces";

@@ -12,3 +12,3 @@ import {

objectSet,
mapOrSetClear
mapOrSetClear,
} from "./objectWrapperHelpers";

@@ -24,3 +24,3 @@

hashMapNodePointerToKeyValue,
hashmapNodesPointerIterator
hashmapNodesPointerIterator,
} from "./hashmap/hashmap";

@@ -73,3 +73,3 @@ import { entryToFinalJavaScriptValue } from "./entryToFinalJavaScriptValue";

this.carrier.uint32[valuePointer / Uint32Array.BYTES_PER_ELEMENT]
)
),
];

@@ -168,6 +168,6 @@ }

externalArgs: ExternalArgs,
dataViewCarrier: GlobalCarrier,
globalCarrier: GlobalCarrier,
entryPointer: number
): Map<K, V> {
return new MapWrapper<K, V>(externalArgs, dataViewCarrier, entryPointer);
return new MapWrapper<K, V>(externalArgs, globalCarrier, entryPointer);
}

@@ -5,3 +5,3 @@ /* eslint-env jest */

createMemoryOperator,
_buildMemoryLayout
_buildMemoryLayout,
} from "./memoryMachinery";

@@ -15,3 +15,3 @@ import { arrayBuffer2HexArray, makeCarrier } from "./testUtils";

Uint32: Uint32Array,
Uint8: Uint8Array
Uint8: Uint8Array,
};

@@ -41,7 +41,7 @@

.filter(([key]) => key !== "SIZE_OF")
.map(entry => [
.map((entry) => [
entry[0],
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
// @ts-ignore
entry[1].type
entry[1].type,
])

@@ -54,3 +54,3 @@ ).toEqual(Object.entries(input));

POINTER_TO_NODE: Uint32Array,
LENGTH_OF_KEY: Uint32Array
LENGTH_OF_KEY: Uint32Array,
});

@@ -194,3 +194,3 @@

POINTER_TO_NODE: Uint32Array,
LENGTH_OF_KEY: Uint32Array
LENGTH_OF_KEY: Uint32Array,
});

@@ -215,3 +215,3 @@

NODE_KEY_POINTER: Uint32Array.BYTES_PER_ELEMENT,
NODE_KEY_LENGTH: Uint16Array.BYTES_PER_ELEMENT
NODE_KEY_LENGTH: Uint16Array.BYTES_PER_ELEMENT,
});

@@ -218,0 +218,0 @@

@@ -7,3 +7,3 @@ import { GlobalCarrier } from "./interfaces";

// BigUint64Array,
Uint16Array
Uint16Array,
] as const;

@@ -38,3 +38,3 @@

// [BigUint64Array, dataViewInstance.getBigUint64, dataViewInstance.setBigUint64],
[Uint16Array, "uint16"]
[Uint16Array, "uint16"],
] as const;

@@ -49,3 +49,3 @@

const READ_WRITE_MAP_V2 = new Map(READ_WRITE_MAPS_V2.map(e => [e[0], e[1]]));
const READ_WRITE_MAP_V2 = new Map(READ_WRITE_MAPS_V2.map((e) => [e[0], e[1]]));

@@ -93,3 +93,3 @@ export interface MemoryOperator<T extends string> {

},
size: memoryMap.SIZE_OF
size: memoryMap.SIZE_OF,
};

@@ -117,4 +117,4 @@ }

(oldEntries[index - 1][1] as any).BYTES_PER_ELEMENT,
type: type as any
}
type: type as any,
},
]);

@@ -128,3 +128,3 @@ }

(oldEntries[newObjectEntries.length - 1][1] as TypedArrayCtor)
.BYTES_PER_ELEMENT
.BYTES_PER_ELEMENT,
]);

@@ -145,3 +145,3 @@

address: number
) => MemoryOperator<T>
) => MemoryOperator<T>,
};

@@ -162,3 +162,3 @@ }

key,
newObjectEntries[index - 1][1] + oldEntries[index - 1][1]
newObjectEntries[index - 1][1] + oldEntries[index - 1][1],
]);

@@ -171,3 +171,3 @@ }

newObjectEntries[newObjectEntries.length - 1][1] +
oldEntries[newObjectEntries.length - 1][1]
oldEntries[newObjectEntries.length - 1][1],
]);

@@ -174,0 +174,0 @@

/* eslint-env jest */
import { initializeArrayBuffer } from "./store";
import * as util from "util";
import { createArrayWrapper } from "./arrayWrapper";

@@ -12,5 +12,3 @@ import { arraySaver } from "./arraySaver";

const externalArgs = externalArgsApiToExternalArgsApi({
textEncoder: new util.TextEncoder(),
textDecoder: new util.TextDecoder(),
arrayAdditionalAllocation: 20
arrayAdditionalAllocation: 20,
});

@@ -17,0 +15,0 @@

/* eslint-env jest */
import { initializeArrayBuffer } from "./store";
import * as util from "util";
import { arrayBuffer2HexArray, makeCarrier } from "./testUtils";

@@ -10,6 +10,3 @@ import { objectSaver } from "./objectSaver";

describe("objectSaver tests", () => {
const externalArgs = externalArgsApiToExternalArgsApi({
textEncoder: new util.TextEncoder(),
textDecoder: new util.TextDecoder()
});
const externalArgs = externalArgsApiToExternalArgsApi({});

@@ -31,7 +28,13 @@ describe("objectSaver - general", () => {

nestedObject: {
nestedProp: 7
}
nestedProp: 7,
},
};
const saverOutput = objectSaver(externalArgs, carrier, [], objectToSave);
const saverOutput = objectSaver(
externalArgs,
carrier,
[],
new Map(),
objectToSave
);

@@ -38,0 +41,0 @@ expect(saverOutput).toMatchInlineSnapshot(`976`);

@@ -8,3 +8,3 @@ import { appendEntry } from "./store";

MapEntry,
SetEntry
SetEntry,
} from "./interfaces";

@@ -18,2 +18,3 @@ import { saveValue } from "./saveValue";

referencedPointers: number[],
visitedValues: Map<object, number>,
objectToSave: any

@@ -25,3 +26,6 @@ ) {

carrier,
Math.max(externalArgs.hashMapMinInitialCapacity, objectEntries.length * 1.3)
Math.max(
externalArgs.hashMapMinInitialCapacity,
Math.ceil(objectEntries.length * 1.3)
)
);

@@ -41,2 +45,3 @@

referencedPointers,
visitedValues,
value

@@ -51,3 +56,3 @@ );

refsCount: 1,
value: hashMapPointer
value: hashMapPointer,
};

@@ -62,2 +67,3 @@

referencedPointers: number[],
visitedValues: Map<object, number>,
mapToSave: Map<string | number, any>

@@ -67,3 +73,6 @@ ) {

carrier,
Math.max(externalArgs.hashMapMinInitialCapacity, mapToSave.size * 1.3)
Math.max(
externalArgs.hashMapMinInitialCapacity,
Math.ceil(mapToSave.size * 1.3)
)
);

@@ -83,2 +92,3 @@

referencedPointers,
visitedValues,
value

@@ -93,3 +103,3 @@ );

refsCount: 1,
value: hashMapPointer
value: hashMapPointer,
};

@@ -107,3 +117,6 @@

carrier,
Math.max(externalArgs.hashMapMinInitialCapacity, setToSave.size * 1.3)
Math.max(
externalArgs.hashMapMinInitialCapacity,
Math.ceil(setToSave.size * 1.3)
)
);

@@ -125,3 +138,3 @@

refsCount: 1,
value: hashMapPointer
value: hashMapPointer,
};

@@ -128,0 +141,0 @@

/* eslint-env jest */
import { initializeArrayBuffer } from "./store";
import * as util from "util";
import { objectSaver } from "./objectSaver";

@@ -11,6 +11,3 @@ import { createObjectWrapper } from "./objectWrapper";

describe("objectWrapper tests", () => {
const externalArgs = externalArgsApiToExternalArgsApi({
textEncoder: new util.TextEncoder(),
textDecoder: new util.TextDecoder()
});
const externalArgs = externalArgsApiToExternalArgsApi({});

@@ -29,7 +26,13 @@ describe("objectWrapper - general", () => {

nestedObject: {
nestedProp: 7
}
nestedProp: 7,
},
};
const saverOutput = objectSaver(externalArgs, carrier, [], objectToSave);
const saverOutput = objectSaver(
externalArgs,
carrier,
[],
new Map(),
objectToSave
);

@@ -73,7 +76,13 @@ const objectWrapper: any = createObjectWrapper(

nestedObject: {
nestedProp: 7
}
nestedProp: 7,
},
};
const saverOutput = objectSaver(externalArgs, carrier, [], objectToSave);
const saverOutput = objectSaver(
externalArgs,
carrier,
[],
new Map(),
objectToSave
);

@@ -104,7 +113,13 @@ const objectWrapper: any = createObjectWrapper(

nestedObject: {
nestedProp: 7
}
nestedProp: 7,
},
};
const saverOutput = objectSaver(externalArgs, carrier, [], objectToSave);
const saverOutput = objectSaver(
externalArgs,
carrier,
[],
new Map(),
objectToSave
);

@@ -146,7 +161,13 @@ const objectWrapper = createObjectWrapper(

nestedObject: {
nestedProp: 7
}
nestedProp: 7,
},
};
const saverOutput = objectSaver(externalArgs, carrier, [], objectToSave);
const saverOutput = objectSaver(
externalArgs,
carrier,
[],
new Map(),
objectToSave
);

@@ -189,7 +210,13 @@ const objectWrapper = createObjectWrapper(

nestedObject: {
nestedProp: 7
}
nestedProp: 7,
},
};
const saverOutput = objectSaver(externalArgs, carrier, [], objectToSave);
const saverOutput = objectSaver(
externalArgs,
carrier,
[],
new Map(),
objectToSave
);

@@ -196,0 +223,0 @@ const objectWrapper = createObjectWrapper(

@@ -6,3 +6,3 @@ import { ObjectEntry, ExternalArgs, GlobalCarrier } from "./interfaces";

objectGet,
objectSet
objectSet,
} from "./objectWrapperHelpers";

@@ -13,3 +13,3 @@

IllegalObjectPropConfigError,
UnsupportedOperationError
UnsupportedOperationError,
} from "./exceptions";

@@ -53,3 +53,3 @@ import { allocationsTransaction } from "./allocationsTransaction";

return gotEntries.map(e => e.key);
return gotEntries.map((e) => e.key);
}

@@ -63,3 +63,3 @@

return gotEntries.map(e => e.key);
return gotEntries.map((e) => e.key);
}

@@ -131,3 +131,3 @@

externalArgs: ExternalArgs,
dataViewCarrier: GlobalCarrier,
globalCarrier: GlobalCarrier,
entryPointer: number

@@ -137,4 +137,4 @@ ): T {

{ objectBufferWrapper: "objectBufferWrapper" },
new ObjectWrapper(externalArgs, dataViewCarrier, entryPointer)
new ObjectWrapper(externalArgs, globalCarrier, entryPointer)
) as any;
}
/* eslint-env jest */
import { initializeArrayBuffer, readEntry } from "./store";
import * as util from "util";
import { objectSaver } from "./objectSaver";
import {
getObjectPropertiesEntries,
deleteObjectPropertyEntryByKey
deleteObjectPropertyEntryByKey,
} from "./objectWrapperHelpers";

@@ -16,5 +16,3 @@ import { externalArgsApiToExternalArgsApi } from "./utils";

const externalArgs = externalArgsApiToExternalArgsApi({
textEncoder: new util.TextEncoder(),
textDecoder: new util.TextDecoder(),
arrayAdditionalAllocation: 20
arrayAdditionalAllocation: 20,
});

@@ -33,7 +31,13 @@

nestedObject: {
nestedProp: 7
}
nestedProp: 7,
},
};
const saverOutput = objectSaver(externalArgs, carrier, [], objectToSave);
const saverOutput = objectSaver(
externalArgs,
carrier,
[],
new Map(),
objectToSave
);

@@ -80,6 +84,12 @@ const hashmapPointer = (readEntry(carrier, saverOutput) as ObjectEntry)

c: undefined,
d: null
d: null,
};
const saverOutput = objectSaver(externalArgs, carrier, [], objectToSave);
const saverOutput = objectSaver(
externalArgs,
carrier,
[],
new Map(),
objectToSave
);

@@ -130,6 +140,12 @@ expect(carrier.allocator.stats().available).toMatchInlineSnapshot(`40`);

c: undefined,
d: null
d: null,
};
const saverOutput = objectSaver(externalArgs, carrier, [], objectToSave);
const saverOutput = objectSaver(
externalArgs,
carrier,
[],
new Map(),
objectToSave
);

@@ -179,6 +195,12 @@ expect(carrier.allocator.stats().available).toMatchInlineSnapshot(`40`);

d: null,
e: 66
e: 66,
};
const saverOutput = objectSaver(externalArgs, carrier, [], objectToSave);
const saverOutput = objectSaver(
externalArgs,
carrier,
[],
new Map(),
objectToSave
);
// expect(carrier.allocator.stats().available).toMatchInlineSnapshot(`8`);

@@ -185,0 +207,0 @@

@@ -7,3 +7,3 @@ import {

MapEntry,
SetEntry
SetEntry,
} from "./interfaces";

@@ -15,3 +15,4 @@ import {

decrementRefCount,
writeEntry
writeEntry,
setRefCount,
} from "./store";

@@ -25,5 +26,5 @@ import { entryToFinalJavaScriptValue } from "./entryToFinalJavaScriptValue";

hashMapValueLookup,
createHashMap
createHashMap,
} from "./hashmap/hashmap";
import { getObjectOrMapOrSetAddresses } from "./getAllLinkedAddresses";
import { getAllLinkedAddresses } from "./getAllLinkedAddresses";

@@ -79,3 +80,3 @@ export function deleteObjectPropertyEntryByKey(

carrier.uint32[valuePointer / Uint32Array.BYTES_PER_ELEMENT],
key: keyEntry.value
key: keyEntry.value,
});

@@ -123,19 +124,49 @@ }

export function hashmapClearFree(
// export function hashmapClearFree(
// externalArgs: ExternalArgs,
// carrier: GlobalCarrier,
// hashmapPointer: number
// ) {
// const leafAddresses = new Set<number>();
// const addressesToProcessQueue: number[] = [];
// getObjectOrMapOrSetAddresses(
// carrier,
// hashmapPointer,
// leafAddresses,
// addressesToProcessQueue
// );
// for (const address of leafAddresses) {
// carrier.allocator.free(address);
// }
// for (const address of arcAddresses) {
// decrementRefCount(externalArgs, carrier, address);
// }
// }
export function mapOrSetClear(
externalArgs: ExternalArgs,
carrier: GlobalCarrier,
hashmapPointer: number
mapOrSetPtr: number
) {
const leafAddresses: number[] = [];
const arcAddresses: number[] = [];
const entry = readEntry(carrier, mapOrSetPtr) as MapEntry | SetEntry;
getObjectOrMapOrSetAddresses(
// we fake the entry refCount as zero so getAllLinkedAddresses will visit what's needed
const prevCount = setRefCount(carrier, mapOrSetPtr, 0);
const { leafAddresses, arcAddresses } = getAllLinkedAddresses(
carrier,
false,
hashmapPointer,
leafAddresses,
arcAddresses
mapOrSetPtr
);
for (const address of leafAddresses) {
// don't dispose the address we need to reuse
if (address === mapOrSetPtr) {
continue;
}
carrier.allocator.free(address);

@@ -145,14 +176,14 @@ }

for (const address of arcAddresses) {
// don't dispose the address we need to reuse
if (address === mapOrSetPtr) {
continue;
}
decrementRefCount(externalArgs, carrier, address);
}
}
export function mapOrSetClear(
externalArgs: ExternalArgs,
carrier: GlobalCarrier,
mapOrSetPtr: number
) {
const entry = readEntry(carrier, mapOrSetPtr) as MapEntry | SetEntry;
// hashmapClearFree(externalArgs, carrier, entry.value);
hashmapClearFree(externalArgs, carrier, entry.value);
// Restore real ref count
setRefCount(carrier, mapOrSetPtr, prevCount);

@@ -159,0 +190,0 @@ entry.value = createHashMap(carrier, externalArgs.hashMapMinInitialCapacity);

import {
primitiveValueToEntry,
isPrimitive,
getOurPointerIfApplicable
getOurPointerIfApplicable,
} from "./utils";

@@ -15,3 +15,3 @@ import { appendEntry } from "./store";

TRUE_KNOWN_ADDRESS,
FALSE_KNOWN_ADDRESS
FALSE_KNOWN_ADDRESS,
} from "./consts";

@@ -26,2 +26,4 @@

referencedPointers: number[],
// Not really working yet. we need iterative saving for it
visitedValuesOnCurrentSaveOperation: Map<object, number>,
value: any

@@ -56,2 +58,7 @@ ) {

referencedPointers.push(valuePointer);
} else if (
(maybeOurPointer = visitedValuesOnCurrentSaveOperation.get(value))
) {
valuePointer = maybeOurPointer;
referencedPointers.push(valuePointer);
} else if (Array.isArray(value)) {

@@ -63,8 +70,16 @@ valuePointer = arraySaver(externalArgs, carrier, referencedPointers, value);

refsCount: 1,
value: value.getTime()
value: value.getTime(),
});
} else if (value instanceof Map) {
valuePointer = mapSaver(externalArgs, carrier, referencedPointers, value);
valuePointer = mapSaver(
externalArgs,
carrier,
referencedPointers,
visitedValuesOnCurrentSaveOperation,
value
);
visitedValuesOnCurrentSaveOperation.set(value, valuePointer);
} else if (value instanceof Set) {
valuePointer = setSaver(externalArgs, carrier, value);
visitedValuesOnCurrentSaveOperation.set(value, valuePointer);
} else if (typeof value === "object") {

@@ -75,4 +90,6 @@ valuePointer = objectSaver(

referencedPointers,
visitedValuesOnCurrentSaveOperation,
value
);
visitedValuesOnCurrentSaveOperation.set(value, valuePointer);
} else {

@@ -79,0 +96,0 @@ throw new Error("unsupported yet");

@@ -5,3 +5,3 @@ import {

MapEntry,
InternalAPI
InternalAPI,
} from "./interfaces";

@@ -11,3 +11,3 @@ import {

objectSet,
mapOrSetClear
mapOrSetClear,
} from "./objectWrapperHelpers";

@@ -23,3 +23,3 @@

hashMapNodePointerToKeyValue,
hashmapNodesPointerIterator
hashmapNodesPointerIterator,
} from "./hashmap/hashmap";

@@ -152,6 +152,6 @@ import { entryToFinalJavaScriptValue } from "./entryToFinalJavaScriptValue";

externalArgs: ExternalArgs,
dataViewCarrier: GlobalCarrier,
globalCarrier: GlobalCarrier,
entryPointer: number
): Set<K> {
return new SetWrapper<K>(externalArgs, dataViewCarrier, entryPointer);
return new SetWrapper<K>(externalArgs, globalCarrier, entryPointer);
}
/* eslint-env jest */
import * as util from "util";
import { sizeOf } from "./sizeOf";

@@ -10,5 +9,3 @@ import { externalArgsApiToExternalArgsApi } from "./utils";

const externalArgs = externalArgsApiToExternalArgsApi({
textEncoder: new util.TextEncoder(),
textDecoder: new util.TextDecoder(),
arrayAdditionalAllocation: 20
arrayAdditionalAllocation: 20,
});

@@ -28,3 +25,3 @@

calcedSize,
realSize: beforeSave - afterSave
realSize: beforeSave - afterSave,
};

@@ -31,0 +28,0 @@ }

@@ -5,3 +5,3 @@ import {

ArrayEntry,
ObjectEntry
ObjectEntry,
} from "./interfaces";

@@ -12,3 +12,3 @@ import {

primitiveValueToEntry,
align
align,
} from "./utils";

@@ -18,3 +18,3 @@ import { ENTRY_TYPE } from "./entry-types";

LINKED_LIST_MACHINE,
LINKED_LIST_ITEM_MACHINE
LINKED_LIST_ITEM_MACHINE,
} from "./linkedList/linkedList";

@@ -63,3 +63,3 @@ import { MAP_MACHINE, NODE_MACHINE } from "./hashmap/memoryLayout";

arrayToSave.length + externalArgs.arrayAdditionalAllocation,
length: arrayToSave.length
length: arrayToSave.length,
};

@@ -79,3 +79,3 @@

memoryAllocated,
numberOfAllocations
numberOfAllocations,
};

@@ -110,3 +110,3 @@ }

refsCount: 0,
value: 0
value: 0,
};

@@ -119,3 +119,3 @@

memoryAllocated,
numberOfAllocations
numberOfAllocations,
};

@@ -136,3 +136,3 @@ }

memoryAllocated: 0,
numberOfAllocations: 0
numberOfAllocations: 0,
};

@@ -146,3 +146,3 @@ }

memoryAllocated: align(sizeOfEntry(entry)),
numberOfAllocations: 1
numberOfAllocations: 1,
};

@@ -157,6 +157,6 @@ } else if (Array.isArray(value)) {

refsCount: 0,
value: value.getTime()
value: value.getTime(),
})
),
numberOfAllocations: 1
numberOfAllocations: 1,
};

@@ -197,3 +197,3 @@ } else if (typeof value === "object") {

const hashMapKeysSize = keysArray
.map(k => sizeOfEntry(primitiveValueToEntry(k)))
.map((k) => sizeOfEntry(primitiveValueToEntry(k)))
.reduce((p, c) => {

@@ -215,4 +215,4 @@ return p + align(c);

hashMapNodesAllocationsSize +
hashMapKeysSize
hashMapKeysSize,
};
}

@@ -7,6 +7,6 @@ /* eslint-env jest */

readEntry,
appendEntry
appendEntry,
} from "./store";
import { ENTRY_TYPE } from "./entry-types";
import * as util from "util";
import { arrayBuffer2HexArray, makeCarrier } from "./testUtils";

@@ -56,3 +56,3 @@ import { ObjectEntry } from "./interfaces";

type: ENTRY_TYPE.NUMBER,
value: Number.MAX_VALUE
value: Number.MAX_VALUE,
});

@@ -89,3 +89,3 @@

type: ENTRY_TYPE.NUMBER,
value: Number.MIN_VALUE
value: Number.MIN_VALUE,
});

@@ -124,3 +124,3 @@

value: "aא弟",
allocatedBytes: 6
allocatedBytes: 6,
});

@@ -157,5 +157,3 @@

const externalArgs = externalArgsApiToExternalArgsApi({
textEncoder: new util.TextEncoder(),
textDecoder: new util.TextDecoder(),
arrayAdditionalAllocation: 20
arrayAdditionalAllocation: 20,
});

@@ -169,3 +167,3 @@

type: ENTRY_TYPE.NUMBER,
value: Number.MAX_VALUE
value: Number.MAX_VALUE,
});

@@ -191,3 +189,3 @@

type: ENTRY_TYPE.NUMBER,
value: Number.MIN_VALUE
value: Number.MIN_VALUE,
});

@@ -212,3 +210,3 @@

value: "aא弟",
allocatedBytes: 6
allocatedBytes: 6,
});

@@ -233,3 +231,3 @@

type: ENTRY_TYPE.BIGINT_POSITIVE,
value: BigInt("0b0" + "1".repeat(63))
value: BigInt("0b0" + "1".repeat(63)),
});

@@ -253,3 +251,3 @@

type: ENTRY_TYPE.BIGINT_POSITIVE,
value: BigInt("0b" + "1".repeat(64))
value: BigInt("0b" + "1".repeat(64)),
});

@@ -272,3 +270,3 @@

type: ENTRY_TYPE.BIGINT_POSITIVE,
value: BigInt("0b" + "1".repeat(64))
value: BigInt("0b" + "1".repeat(64)),
});

@@ -290,3 +288,3 @@

type: ENTRY_TYPE.BIGINT_NEGATIVE,
value: -BigInt("0b" + "1".repeat(64))
value: -BigInt("0b" + "1".repeat(64)),
});

@@ -309,3 +307,3 @@

type: ENTRY_TYPE.BIGINT_POSITIVE,
value: BigInt("0b" + "1".repeat(65))
value: BigInt("0b" + "1".repeat(65)),
});

@@ -323,3 +321,3 @@ }).toThrowErrorMatchingInlineSnapshot(`"BigInt64OverflowError"`);

refsCount: 0,
value: 10
value: 10,
};

@@ -351,3 +349,3 @@

value: "im a string",
allocatedBytes: 11
allocatedBytes: 11,
});

@@ -354,0 +352,0 @@

@@ -6,3 +6,3 @@ import { ENTRY_TYPE, isPrimitiveEntryType } from "./entry-types";

primitiveValueToEntry,
isKnownAddressValuePointer
isKnownAddressValuePointer,
} from "./utils";

@@ -13,3 +13,3 @@ import { ExternalArgs } from "./interfaces";

INITIAL_ENTRY_POINTER_TO_POINTER,
INITIAL_ENTRY_POINTER_VALUE
INITIAL_ENTRY_POINTER_VALUE,
} from "./consts";

@@ -134,3 +134,3 @@ import { saveValue } from "./saveValue";

writtenBytes,
allocatedBytes: entry.allocatedBytes
allocatedBytes: entry.allocatedBytes,
},

@@ -218,3 +218,3 @@ true

type: entryType,
value: undefined as any
value: undefined as any,
};

@@ -369,2 +369,3 @@

referencedPointers,
new Map(),
value

@@ -378,3 +379,3 @@ );

existingEntryPointer,
existingValueEntry
existingValueEntry,
};

@@ -393,3 +394,3 @@ }

existingEntryPointer = 0,
referencedPointers = []
referencedPointers = [],
} = writeValueInPtrToPtr(externalArgs, carrier, ptrToPtr, value) || {};

@@ -502,2 +503,29 @@

export function getRefCount(carrier: GlobalCarrier, entryPointer: number) {
const entry = readEntry(carrier, entryPointer);
if ("refsCount" in entry) {
return entry.refsCount;
}
throw new Error("unexpected");
}
export function setRefCount(
carrier: GlobalCarrier,
entryPointer: number,
newRefCount: number
) {
const entry = readEntry(carrier, entryPointer);
if ("refsCount" in entry) {
const prevCount = entry.refsCount;
entry.refsCount = newRefCount;
writeEntry(carrier, entryPointer, entry);
return prevCount;
}
throw new Error("unexpected");
}
// export function getObjectPropPtrToPtr(

@@ -504,0 +532,0 @@ // { dataView }: GlobalCarrier,

@@ -19,4 +19,4 @@ /* eslint-env jest */

`請教「署」在文中的含義。 文句中「署」是什么意思?「使直言署」,及下文的「署帛宛然」a`,
125
]
125,
],
];

@@ -23,0 +23,0 @@

@@ -21,4 +21,4 @@ /* eslint-env jest */

`請教「署」在文中的含義。 文句中「署」是什么意思?「使直言署」,及下文的「署帛宛然」`,
124
]
124,
],
];

@@ -25,0 +25,0 @@

@@ -17,3 +17,3 @@ export function arrayBuffer2HexArray(

export function wait(time: number) {
return new Promise(res => {
return new Promise((res) => {
// eslint-disable-next-line no-undef

@@ -102,3 +102,3 @@ setTimeout(res, time);

buf: arrayBuffer,
start: MEM_POOL_START
start: MEM_POOL_START,
});

@@ -113,3 +113,3 @@

float64: new Float64Array(arrayBuffer),
bigUint64: new BigUint64Array(arrayBuffer)
bigUint64: new BigUint64Array(arrayBuffer),
};

@@ -116,0 +116,0 @@

@@ -6,3 +6,3 @@ import {

InternalAPI,
ExternalArgsApi
ExternalArgsApi,
} from "./interfaces";

@@ -15,3 +15,3 @@ import { ENTRY_TYPE } from "./entry-types";

TRUE_KNOWN_ADDRESS,
FALSE_KNOWN_ADDRESS
FALSE_KNOWN_ADDRESS,
} from "./consts";

@@ -25,3 +25,3 @@ import { IMemPool } from "@thi.ng/malloc";

"boolean",
"undefined"
"undefined",
] as const;

@@ -46,3 +46,3 @@

value,
allocatedBytes: strByteLength(value)
allocatedBytes: strByteLength(value),
};

@@ -54,3 +54,3 @@ }

type: ENTRY_TYPE.NUMBER,
value
value,
};

@@ -65,3 +65,3 @@ }

: ENTRY_TYPE.BIGINT_NEGATIVE,
value
value,
};

@@ -118,3 +118,3 @@ }

? p.arrayAdditionalAllocation
: 0
: 0,
};

@@ -121,0 +121,0 @@ }

@@ -6,2 +6,3 @@ const KEYS = 1;

declare const FinalizationGroup: any;
declare const FinalizationRegistry: any;
declare const WeakRef: any;

@@ -25,3 +26,8 @@

this.group = new FinalizationGroup((iterator: Iterable<any>) => {
const FinalizationSomething =
typeof FinalizationRegistry !== "undefined"
? FinalizationRegistry
: FinalizationGroup;
this.group = new FinalizationSomething((iterator: Iterable<any>) => {
for (const key of iterator) {

@@ -28,0 +34,0 @@ this.map.delete(key);

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

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

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

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

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

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

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

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