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

@magnetarjs/core

Package Overview
Dependencies
Maintainers
3
Versions
152
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@magnetarjs/core - npm Package Compare versions

Comparing version 0.20.1 to 1.0.1

dist/Collection.d.ts

21

dist/index.d.ts

@@ -1,20 +0,3 @@

import { GlobalConfig, MagnetarInstance, WriteLock } from '@magnetarjs/types';
export * from '@magnetarjs/types';
/**
* Creates a magnetar instance.
* @see {@link GlobalConfig}
* @see {@link MagnetarInstance}
*/
declare function Magnetar(magnetarConfig: GlobalConfig): MagnetarInstance;
/**
* Returns a tuple with `[CollectionPath, DocId]` if the `DocId` is `undefined` that means that the `modulePath` passed is a collection!
*/
declare function getCollectionPathDocIdEntry(modulePath: string): [CollectionPath: string, DocId: string | undefined];
/**
* Gets all WriteLock objects of a certain `collectionPath` from the `WriteLockMap`
*/
declare function getCollectionWriteLocks(collectionPath: string, writeLockMap: Map<string, WriteLock>): WriteLock[];
export { Magnetar, getCollectionPathDocIdEntry, getCollectionWriteLocks };
export * from './Magnetar.js';
export * from './helpers/pathHelpers.js';

@@ -1,963 +0,3 @@

"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/index.ts
var src_exports = {};
__export(src_exports, {
Magnetar: () => Magnetar,
getCollectionPathDocIdEntry: () => getCollectionPathDocIdEntry,
getCollectionWriteLocks: () => getCollectionWriteLocks
});
module.exports = __toCommonJS(src_exports);
__reExport(src_exports, require("@magnetarjs/types"), module.exports);
// src/Magnetar.ts
var import_types3 = require("@magnetarjs/types");
var import_getorset_anything2 = require("getorset-anything");
var import_is_what7 = require("is-what");
// src/Collection.ts
var import_types = require("@magnetarjs/types");
var import_merge_anything = require("merge-anything");
// src/helpers/moduleHelpers.ts
var import_is_what2 = require("is-what");
// src/helpers/throwFns.ts
var import_utils = require("@magnetarjs/utils");
var import_is_what = require("is-what");
function logError(errorMessage) {
console.error("[@magnetarjs error]\n", errorMessage);
}
function logErrorAndThrow(errorMessage) {
logError(errorMessage);
throw new Error(errorMessage);
}
function throwOnIncompleteStreamResponses(streamInfoPerStore, doOnStreamFns) {
const noStreamLogic = !Object.keys(streamInfoPerStore).length;
if (noStreamLogic) {
const errorMessage = "None of your store plugins have implemented logic to open a stream.";
logErrorAndThrow(errorMessage);
}
const noDoOnStreamLogic = !Object.values(doOnStreamFns).flat().length;
if (noDoOnStreamLogic) {
const errorMessage = "None of your store plugins have implemented logic to do something with the data coming in from streams.";
logErrorAndThrow(errorMessage);
}
}
function throwIfNoFnsToExecute(storesToExecute) {
if (storesToExecute.length === 0) {
const errorMessage = "None of your store plugins have implemented this function or you have not defined an executionOrder anywhere.";
logErrorAndThrow(errorMessage);
}
}
function throwIfNolocalStoreName(localStoreName) {
if ((0, import_is_what.isFullString)(localStoreName))
return;
const errorMessage = `No 'localStoreName' provided.`;
logErrorAndThrow(errorMessage);
}
function throwIfInvalidModulePath(modulePath, moduleType) {
let errorMessage = "";
if (moduleType === "collection") {
if (!modulePath)
errorMessage = 'You must provide a collection id (or a "path" like so: collection/doc/collection).';
if ((0, import_utils.isDocModule)(modulePath))
errorMessage = `Your collection id (or "path") must be of odd segments. The expected pattern is: collection/doc/collection ... Yours was ${modulePath}`;
}
if (moduleType === "doc") {
if (!modulePath)
errorMessage = 'You must provide a document id (or a "path" like so: collection/doc).';
if ((0, import_utils.isCollectionModule)(modulePath))
errorMessage = `Your doc id (or "path") must be of even segments. The expected pattern is: collection/doc/collection/doc ... Yours was ${modulePath}`;
}
if (errorMessage)
logErrorAndThrow(errorMessage);
}
// src/helpers/moduleHelpers.ts
function getPluginModuleConfig(moduleConfig, storeName) {
const { query, where, orderBy, limit, startAfter, configPerStore = {} } = moduleConfig;
const extraStoreConfig = (0, import_is_what2.isPlainObject)(configPerStore[storeName]) ? configPerStore[storeName] : {};
return { ...extraStoreConfig, query, where, orderBy, limit, startAfter };
}
function executeSetupModulePerStore(globalConfigStores, [collectionPath, docId], moduleConfig) {
for (const storeName in globalConfigStores) {
const { setupModule } = globalConfigStores[storeName];
if ((0, import_is_what2.isFunction)(setupModule)) {
const pluginModuleConfig = getPluginModuleConfig(moduleConfig, storeName);
setupModule({ collectionPath, docId, pluginModuleConfig });
}
}
}
function getDataFromDataStore(moduleConfig, globalConfig, collectionPath, docId) {
const localStoreName = globalConfig.localStoreName;
throwIfNolocalStoreName(localStoreName);
const getModuleData = globalConfig.stores[localStoreName].getModuleData;
if (!getModuleData) {
throw new Error("The data store did not provide a getModuleData function!");
}
const pluginModuleConfig = getPluginModuleConfig(moduleConfig, localStoreName);
return getModuleData({ collectionPath, docId, pluginModuleConfig });
}
function getExistsFromDataStore(globalConfig, collectionPath, docId) {
const localStoreName = globalConfig.localStoreName;
throwIfNolocalStoreName(localStoreName);
const getModuleExists = globalConfig.stores[localStoreName].getModuleExists;
if (!getModuleExists) {
throw new Error("The data store did not provide a getModuleExists function!");
}
return getModuleExists({ collectionPath, docId });
}
function getCountFromDataStore(moduleConfig, globalConfig, collectionPath) {
const localStoreName = globalConfig.localStoreName;
throwIfNolocalStoreName(localStoreName);
const getModuleCount = globalConfig.stores[localStoreName].getModuleCount;
if (!getModuleCount) {
throw new Error("The data store did not provide a getModuleCount function!");
}
const pluginModuleConfig = getPluginModuleConfig(moduleConfig, localStoreName);
return getModuleCount({ collectionPath, pluginModuleConfig });
}
function proxify(target, propExecutionDic) {
const dataHandler = {
get: function(target2, key, proxyRef) {
if (key in propExecutionDic) {
return propExecutionDic[key]();
}
return Reflect.get(target2, key, proxyRef);
}
};
return new Proxy(target, dataHandler);
}
// src/moduleActions/handleActionPerStore.ts
var import_getorset_anything = require("getorset-anything");
var import_is_what4 = require("is-what");
// src/helpers/eventHelpers.ts
function getEventNameFnsMap(...onMaps) {
const _onMaps = onMaps.filter(Boolean);
const result = {
before: _onMaps.flatMap((on) => on.before ?? []),
success: _onMaps.flatMap((on) => on.success ?? []),
error: _onMaps.flatMap((on) => on.error ?? []),
revert: _onMaps.flatMap((on) => on.revert ?? [])
};
return result;
}
// src/helpers/executeOnFns.ts
function executeOnFns(params) {
const { modifyReadResultFns, localStoreFns, payload, docMetaData } = params;
let newPayload = payload;
for (const fn of modifyReadResultFns) {
if (newPayload)
newPayload = fn(newPayload, docMetaData);
}
for (const fn of localStoreFns) {
newPayload = fn(newPayload, docMetaData);
}
return newPayload;
}
// src/helpers/modifyPayload.ts
function getModifyPayloadFnsMap(...onMaps) {
const _onMaps = onMaps.filter(Boolean);
const writeFns = _onMaps.flatMap((on) => on.write ?? []);
const readFns = _onMaps.flatMap((on) => on.read ?? []);
const result = {
insert: _onMaps.flatMap((on) => on.insert ?? []).concat(writeFns),
merge: _onMaps.flatMap((on) => on.merge ?? []).concat(writeFns),
assign: _onMaps.flatMap((on) => on.assign ?? []).concat(writeFns),
replace: _onMaps.flatMap((on) => on.replace ?? []).concat(writeFns),
deleteProp: _onMaps.flatMap((on) => on.deleteProp ?? []),
delete: [],
// delete has no payload
stream: _onMaps.flatMap((on) => on.stream ?? []).concat(readFns),
fetch: _onMaps.flatMap((on) => on.fetch ?? []).concat(readFns)
};
return result;
}
// src/helpers/modifyReadResponse.ts
function getModifyReadResponseFnsMap(...onMaps) {
const _onMaps = onMaps.filter(Boolean);
const result = {
added: _onMaps.flatMap((on) => on.added ?? []),
modified: _onMaps.flatMap((on) => on.modified ?? []),
removed: _onMaps.flatMap((on) => on.removed ?? [])
};
return result;
}
// src/helpers/pathHelpers.ts
var import_utils2 = require("@magnetarjs/utils");
function getCollectionPathDocIdEntry(modulePath) {
if ((0, import_utils2.isCollectionModule)(modulePath))
return [modulePath, void 0];
const collectionPath = modulePath.split("/").slice(0, -1).join("/");
const docId = modulePath.split("/").slice(-1)[0];
return [collectionPath, docId];
}
function getCollectionWriteLocks(collectionPath, writeLockMap) {
return [...writeLockMap.entries()].filter(([modulePath]) => {
const [_collectionPath] = getCollectionPathDocIdEntry(modulePath);
return _collectionPath === collectionPath;
}).map(([modulePath, writeLock]) => writeLock);
}
// src/helpers/pluginHelpers.ts
var import_is_what3 = require("is-what");
function isDoOnStream(payload) {
const isNotDoOnStream = !(0, import_is_what3.isPlainObject)(payload) || payload.streaming || payload.stop || !(payload.added || payload.modified || payload.removed);
return !isNotDoOnStream;
}
function isDoOnFetchCount(payload) {
return (0, import_is_what3.isFunction)(payload);
}
function isFetchCountResponse(payload) {
return (0, import_is_what3.isPlainObject)(payload) && (0, import_is_what3.isNumber)(payload.count);
}
function isDoOnFetch(payload) {
return (0, import_is_what3.isFunction)(payload);
}
function isFetchResponse(payload) {
return (0, import_is_what3.isPlainObject)(payload) && (0, import_is_what3.isArray)(payload.docs);
}
// src/moduleActions/handleAction.ts
async function handleAction(args) {
const {
collectionPath,
docId,
modulePath,
pluginModuleConfig,
pluginAction,
payload,
actionConfig = {},
eventNameFnsMap: on,
onError,
actionName,
stopExecutionAfterAction,
storeName
} = args;
let abortExecution = false;
const abort = () => {
abortExecution = true;
};
for (const fn of on.before) {
await fn({ payload, actionName, storeName, abort, collectionPath, docId, path: modulePath, pluginModuleConfig });
}
if (abortExecution) {
stopExecutionAfterAction();
return;
}
let result;
try {
result = await pluginAction({
payload,
actionConfig,
collectionPath,
docId,
pluginModuleConfig
});
} catch (error) {
for (const fn of on.error) {
await fn({ payload, actionName, storeName, abort, error, collectionPath, docId, path: modulePath, pluginModuleConfig });
}
if (abortExecution || onError === "stop") {
stopExecutionAfterAction();
throw error;
}
if (onError === "revert") {
stopExecutionAfterAction("revert");
}
return error;
}
for (const fn of on.success) {
await fn({ payload, result, actionName, storeName, abort, collectionPath, docId, path: modulePath, pluginModuleConfig });
}
if (abortExecution) {
stopExecutionAfterAction();
return result;
}
return result;
}
// src/moduleActions/handleActionPerStore.ts
function handleActionPerStore(sharedParams, actionName, actionType) {
const { collectionPath, _docId, moduleConfig, globalConfig, fetchPromises, writeLockMap, docFn, collectionFn, setLastFetched } = sharedParams;
return function(payload, actionConfig = {}) {
const fetchPromiseKey = JSON.stringify(payload);
const foundFetchPromise = fetchPromises.get(fetchPromiseKey);
if (actionName === "fetch" && (0, import_is_what4.isPromise)(foundFetchPromise))
return foundFetchPromise;
const writeLockId = _docId ? `${collectionPath}/${_docId}` : collectionPath;
const writeLock = (0, import_getorset_anything.mapGetOrSet)(writeLockMap, writeLockId, () => {
return { promise: null, resolve: () => {
}, countdown: null };
});
if (actionName !== "fetch" && actionName !== "fetchCount") {
if (writeLock.promise === null) {
writeLock.promise = new Promise((resolve) => {
writeLock.resolve = () => {
resolve();
writeLock.resolve = () => {
};
writeLock.promise = null;
if (writeLock.countdown !== null) {
clearTimeout(writeLock.countdown);
writeLock.countdown = null;
}
};
});
}
if (writeLock.promise !== null && writeLock.countdown !== null) {
clearTimeout(writeLock.countdown);
writeLock.countdown = null;
}
}
const actionPromise = new Promise(async (resolve, reject) => {
const force = payload?.force === true;
if (actionName === "fetch" && force) {
await writeLock.promise;
if (!_docId) {
const collectionWriteMaps = getCollectionWriteLocks(collectionPath, writeLockMap);
await Promise.allSettled(collectionWriteMaps.map((w) => w.promise));
}
}
try {
let stopExecutionAfterAction2 = function(trueOrRevert = true) {
stopExecution = trueOrRevert;
};
var stopExecutionAfterAction = stopExecutionAfterAction2;
let docId = _docId;
let modulePath = [collectionPath, docId].filter(Boolean).join("/");
const onError = actionConfig.onError || moduleConfig.onError || globalConfig.onError;
const modifyPayloadFnsMap = getModifyPayloadFnsMap(
globalConfig.modifyPayloadOn,
moduleConfig.modifyPayloadOn,
actionConfig.modifyPayloadOn
);
const modifyReadResponseMap = getModifyReadResponseFnsMap(
globalConfig.modifyReadResponseOn,
moduleConfig.modifyReadResponseOn,
actionConfig.modifyReadResponseOn
);
const eventNameFnsMap = getEventNameFnsMap(
globalConfig.on,
moduleConfig.on,
actionConfig.on
);
const storesToExecute = actionConfig.executionOrder || (moduleConfig.executionOrder || {})[actionName] || (moduleConfig.executionOrder || {})[actionType] || (globalConfig.executionOrder || {})[actionName] || (globalConfig.executionOrder || {})[actionType] || [];
throwIfNoFnsToExecute(storesToExecute);
if (actionName !== "fetchCount") {
for (const modifyFn of modifyPayloadFnsMap[actionName]) {
payload = modifyFn(payload, docId);
}
}
let stopExecution = false;
const doOnAddedFns = modifyReadResponseMap.added;
const doOnFetchFns = [];
const doOnFetchCountFns = [];
const collectionFetchResult = /* @__PURE__ */ new Map();
let fetchCount = NaN;
let resultFromPlugin;
for (const [i, storeName] of storesToExecute.entries()) {
if (stopExecution === true)
break;
const pluginAction = globalConfig.stores[storeName].actions[actionName];
const pluginModuleConfig = getPluginModuleConfig(moduleConfig, storeName);
resultFromPlugin = !pluginAction ? resultFromPlugin : await handleAction({
collectionPath,
docId,
modulePath,
pluginModuleConfig,
pluginAction,
payload,
// should always use the payload as passed originally for clarity
actionConfig,
eventNameFnsMap,
onError,
actionName,
stopExecutionAfterAction: stopExecutionAfterAction2,
storeName
});
if (stopExecution === "revert") {
const storesToRevert = storesToExecute.slice(0, i);
storesToRevert.reverse();
for (const storeToRevert of storesToRevert) {
const pluginRevertAction = globalConfig.stores[storeToRevert].revert;
const pluginModuleConfig2 = getPluginModuleConfig(moduleConfig, storeToRevert);
await pluginRevertAction({
payload,
actionConfig,
collectionPath,
docId,
pluginModuleConfig: pluginModuleConfig2,
actionName,
error: resultFromPlugin
// in this case the result is the error
});
for (const fn of eventNameFnsMap.revert) {
await fn({ payload, result: resultFromPlugin, actionName, storeName, collectionPath, docId, path: modulePath, pluginModuleConfig: pluginModuleConfig2 });
}
}
if (actionName === "fetch" && docId) {
doOnFetchFns.forEach((fn) => fn(void 0, "error"));
}
if (actionName !== "fetch" && actionName !== "fetchCount") {
writeLock.resolve();
}
throw resultFromPlugin;
}
if (actionName === "insert") {
if (!docId) {
if ((0, import_is_what4.isFullString)(resultFromPlugin)) {
docId = resultFromPlugin;
}
if ((0, import_is_what4.isFullArray)(resultFromPlugin) && (0, import_is_what4.isFullString)(resultFromPlugin[0])) {
docId = resultFromPlugin[0];
}
modulePath = [collectionPath, docId].filter(Boolean).join("/");
}
}
if (actionName === "fetch") {
if (isDoOnFetch(resultFromPlugin)) {
doOnFetchFns.push(resultFromPlugin);
}
if (isFetchResponse(resultFromPlugin)) {
const { docs, reachedEnd, cursor } = resultFromPlugin;
if ((0, import_is_what4.isBoolean)(reachedEnd))
setLastFetched?.({ reachedEnd, cursor });
for (const docMetaData of docs) {
const docResult = executeOnFns({
modifyReadResultFns: doOnAddedFns,
localStoreFns: doOnFetchFns,
payload: docMetaData.data,
docMetaData
});
if (docResult)
collectionFetchResult.set(docMetaData.id, docResult);
const optimisticFetch = !force;
if (optimisticFetch) {
stopExecutionAfterAction2(true);
}
}
}
}
if (actionName === "fetchCount") {
if (isDoOnFetchCount(resultFromPlugin)) {
doOnFetchCountFns.push(resultFromPlugin);
}
if (isFetchCountResponse(resultFromPlugin)) {
for (const doOnFetchCountFn of doOnFetchCountFns) {
doOnFetchCountFn(resultFromPlugin);
}
if (isNaN(fetchCount) || resultFromPlugin.count > fetchCount) {
fetchCount = resultFromPlugin.count;
}
}
}
}
if (actionName === "fetchCount") {
resolve(fetchCount);
return;
}
if (actionName !== "fetch" && !writeLock.countdown) {
writeLock.countdown = setTimeout(writeLock.resolve, 5e3);
}
if (actionName === "insert" && docId) {
resolve(docFn(modulePath, moduleConfig));
return;
}
if (docId || !collectionFn) {
resolve(docFn(modulePath, moduleConfig).data);
if (actionName === "fetch")
fetchPromises.delete(fetchPromiseKey);
return;
}
resolve(collectionFetchResult);
if (actionName === "fetch")
fetchPromises.delete(fetchPromiseKey);
} catch (error) {
reject(error);
if (actionName === "fetch")
fetchPromises.delete(fetchPromiseKey);
}
});
if (actionName === "fetch") {
fetchPromises.set(fetchPromiseKey, actionPromise);
}
return actionPromise;
};
}
// src/moduleActions/handleStreamPerStore.ts
var import_is_what6 = require("is-what");
// src/helpers/writeLockHelpers.ts
var import_is_what5 = require("is-what");
async function writeLockPromise(writeLockMap, docIdentifier) {
const writeLock = writeLockMap.get(docIdentifier);
if (writeLock && (0, import_is_what5.isPromise)(writeLock.promise)) {
await writeLock.promise;
}
}
async function getDocAfterWritelock(params) {
const { writeLockMap, lastIncomingDocs, docIdentifier, payload, meta } = params;
lastIncomingDocs.set(docIdentifier, { payload, meta });
await writeLockPromise(writeLockMap, docIdentifier);
const lastIncoming = lastIncomingDocs.get(docIdentifier);
if (!lastIncoming) {
return;
}
lastIncomingDocs.delete(docIdentifier);
return lastIncoming;
}
// src/moduleActions/handleStream.ts
async function handleStream(args) {
const {
collectionPath,
docId,
pluginModuleConfig,
pluginAction,
payload,
actionConfig = {},
eventNameFnsMap: on,
actionName,
storeName,
mustExecuteOnRead
} = args;
const abort = () => {
};
const path = [collectionPath, docId].filter(Boolean).join("/");
for (const fn of on.before) {
await fn({ payload, actionName, storeName, abort, collectionPath, docId, path, pluginModuleConfig });
}
let result;
try {
const pluginStreamAction = pluginAction;
result = await pluginStreamAction({
payload,
actionConfig,
collectionPath,
docId,
pluginModuleConfig,
mustExecuteOnRead
});
} catch (error) {
for (const fn of on.error) {
await fn({ payload, actionName, storeName, error, abort, collectionPath, docId, path, pluginModuleConfig });
}
throw error;
}
for (const fn of on.success) {
await fn({ payload, result, actionName, storeName, abort, collectionPath, docId, path, pluginModuleConfig });
}
return result;
}
// src/moduleActions/handleStreamPerStore.ts
function handleStreamPerStore([collectionPath, docId], moduleConfig, globalConfig, actionType, streaming, cacheStream, writeLockMap) {
return async function(payload, actionConfig = {}) {
const foundStream = streaming();
if ((0, import_is_what6.isPromise)(foundStream))
return foundStream;
const eventNameFnsMap = getEventNameFnsMap(globalConfig.on, moduleConfig.on, actionConfig.on);
const modifyPayloadFnsMap = getModifyPayloadFnsMap(
globalConfig.modifyPayloadOn,
moduleConfig.modifyPayloadOn,
actionConfig.modifyPayloadOn
);
const modifyReadResponseMap = getModifyReadResponseFnsMap(
globalConfig.modifyReadResponseOn,
moduleConfig.modifyReadResponseOn,
actionConfig.modifyReadResponseOn
);
const storesToExecute = actionConfig.executionOrder || (moduleConfig.executionOrder || {})["stream"] || (moduleConfig.executionOrder || {})[actionType] || (globalConfig.executionOrder || {})["stream"] || (globalConfig.executionOrder || {})[actionType] || [];
throwIfNoFnsToExecute(storesToExecute);
for (const modifyFn of modifyPayloadFnsMap["stream"]) {
payload = modifyFn(payload, docId);
}
const streamInfoPerStore = {};
const modifyReadResponseFns = {
added: modifyReadResponseMap.added,
modified: modifyReadResponseMap.modified,
removed: modifyReadResponseMap.removed
};
const doOnStreamFns = {
added: [],
modified: [],
removed: []
};
const lastIncomingDocs = /* @__PURE__ */ new Map();
const mustExecuteOnRead = {
added: async (_payload, _meta) => {
const docIdentifier = `${collectionPath}/${_meta.id}`;
const result = await getDocAfterWritelock({
writeLockMap,
docIdentifier,
lastIncomingDocs,
meta: _meta,
payload: _payload
});
if (!result)
return;
return executeOnFns({
modifyReadResultFns: modifyReadResponseFns.added,
localStoreFns: doOnStreamFns.added,
payload: result.payload,
docMetaData: result.meta
});
},
modified: async (_payload, _meta) => {
const docIdentifier = `${collectionPath}/${_meta.id}`;
const result = await getDocAfterWritelock({
writeLockMap,
docIdentifier,
lastIncomingDocs,
meta: _meta,
payload: _payload
});
if (!result)
return;
return executeOnFns({
modifyReadResultFns: modifyReadResponseFns.added,
localStoreFns: doOnStreamFns.added,
payload: result.payload,
docMetaData: result.meta
});
},
removed: async (_payload, _meta) => {
const docIdentifier = `${collectionPath}/${_meta.id}`;
lastIncomingDocs.delete(docIdentifier);
await writeLockPromise(writeLockMap, docIdentifier);
return executeOnFns({
modifyReadResultFns: modifyReadResponseFns.removed,
localStoreFns: doOnStreamFns.removed,
payload: _payload,
docMetaData: _meta
});
}
};
for (const storeName of storesToExecute) {
const pluginAction = globalConfig.stores[storeName].actions["stream"];
const pluginModuleConfig = getPluginModuleConfig(moduleConfig, storeName);
if (pluginAction) {
const result = await handleStream({
collectionPath,
docId,
pluginModuleConfig,
pluginAction,
actionConfig,
payload,
// should always use the payload as passed originally for clarity
eventNameFnsMap,
actionName: "stream",
storeName,
mustExecuteOnRead
});
if (isDoOnStream(result)) {
for (const [doOn, doFn] of Object.entries(result)) {
if (doFn)
doOnStreamFns[doOn].push(doFn);
}
}
if (!isDoOnStream(result)) {
streamInfoPerStore[storeName] = result;
}
}
}
throwOnIncompleteStreamResponses(streamInfoPerStore, doOnStreamFns);
const closeStream = () => {
Object.values(streamInfoPerStore).forEach(({ stop }) => stop());
cacheStream(() => {
}, null);
};
const streamPromises = Object.values(streamInfoPerStore).map((res) => res.streaming);
const streamPromise = new Promise((resolve, reject) => {
Promise.all(streamPromises).then(() => {
resolve();
closeStream();
}).catch((e) => {
reject(e);
closeStream();
});
});
cacheStream(closeStream, streamPromise);
return streamPromise;
};
}
// src/Collection.ts
function createCollectionWithContext(collectionPath, moduleConfig, globalConfig, docFn, collectionFn, streamAndFetchPromises, fetchMeta) {
const { writeLockMap, fetchPromises, cacheStream, streaming, closeStream, closeAllStreams } = streamAndFetchPromises;
const id = collectionPath.split("/").slice(-1)[0];
const path = collectionPath;
const doc = (docId, _moduleConfig = {}) => {
return docFn(`${path}/${docId}`, (0, import_merge_anything.merge)(moduleConfig, _moduleConfig));
};
const sharedParams = {
collectionPath,
_docId: void 0,
moduleConfig,
globalConfig,
fetchPromises,
writeLockMap,
docFn,
collectionFn,
setLastFetched: fetchMeta.set
};
const insert = handleActionPerStore(sharedParams, "insert", import_types.actionNameTypeMap.insert);
const _delete = handleActionPerStore(sharedParams, "delete", import_types.actionNameTypeMap.delete);
const fetch = handleActionPerStore(sharedParams, "fetch", import_types.actionNameTypeMap.fetch);
const fetchCount = handleActionPerStore(sharedParams, "fetchCount", import_types.actionNameTypeMap.fetchCount);
const stream = handleStreamPerStore([collectionPath, void 0], moduleConfig, globalConfig, import_types.actionNameTypeMap.stream, streaming, cacheStream, writeLockMap);
const actions = { stream, fetch, fetchCount, insert, delete: _delete };
executeSetupModulePerStore(globalConfig.stores, [collectionPath, void 0], moduleConfig);
function query(query2) {
const moduleConfigWithClause = (0, import_merge_anything.mergeAndConcat)(moduleConfig, { query: [query2] });
return collectionFn(path, moduleConfigWithClause);
}
function where(fieldPath, operator, value) {
const whereClause = [fieldPath, operator, value];
const moduleConfigWithClause = (0, import_merge_anything.mergeAndConcat)(moduleConfig, { where: [whereClause] });
return collectionFn(path, moduleConfigWithClause);
}
function orderBy(fieldPath, direction = "asc") {
const orderByClause = [fieldPath, direction];
const moduleConfigWithClause = (0, import_merge_anything.mergeAndConcat)(moduleConfig, { orderBy: [orderByClause] });
return collectionFn(path, moduleConfigWithClause);
}
function limit(limitCount) {
return collectionFn(path, { ...moduleConfig, limit: limitCount });
}
function startAfter(...values) {
if (values[0] === void 0)
return collectionFn(path, moduleConfig);
const isDoc = values[0] && typeof values[0] === "object";
return collectionFn(path, {
...moduleConfig,
startAfter: isDoc ? values[0] : values
});
}
const queryFns = { query, where, orderBy, limit, startAfter };
const moduleInstance = {
doc,
id,
path,
streaming,
closeStream,
closeAllStreams,
...actions,
...queryFns
};
return proxify(moduleInstance, {
count: () => getCountFromDataStore(moduleConfig, globalConfig, collectionPath),
data: () => getDataFromDataStore(moduleConfig, globalConfig, collectionPath),
fetched: fetchMeta.get
});
}
// src/Doc.ts
var import_types2 = require("@magnetarjs/types");
function createDocWithContext([collectionPath, docId], moduleConfig, globalConfig, docFn, collectionFn, streamAndFetchPromises) {
const { writeLockMap, fetchPromises, cacheStream, streaming, closeStream } = streamAndFetchPromises;
const path = [collectionPath, docId].join("/");
const collection = (collectionId, _moduleConfig = {}) => {
return collectionFn(`${path}/${collectionId}`, _moduleConfig);
};
const sharedParams = {
collectionPath,
_docId: docId,
moduleConfig,
globalConfig,
fetchPromises,
writeLockMap,
docFn
};
const actions = {
insert: handleActionPerStore(sharedParams, "insert", import_types2.actionNameTypeMap.insert),
// prettier-ignore
merge: handleActionPerStore(sharedParams, "merge", import_types2.actionNameTypeMap.merge),
// prettier-ignore
assign: handleActionPerStore(sharedParams, "assign", import_types2.actionNameTypeMap.assign),
// prettier-ignore
replace: handleActionPerStore(sharedParams, "replace", import_types2.actionNameTypeMap.replace),
// prettier-ignore
deleteProp: handleActionPerStore(sharedParams, "deleteProp", import_types2.actionNameTypeMap.deleteProp),
// prettier-ignore
delete: handleActionPerStore(sharedParams, "delete", import_types2.actionNameTypeMap.delete),
// prettier-ignore
fetch: handleActionPerStore(sharedParams, "fetch", import_types2.actionNameTypeMap.fetch),
// prettier-ignore
stream: handleStreamPerStore([collectionPath, docId], moduleConfig, globalConfig, import_types2.actionNameTypeMap.stream, streaming, cacheStream, writeLockMap)
// prettier-ignore
};
executeSetupModulePerStore(globalConfig.stores, [collectionPath, docId], moduleConfig);
const moduleInstance = {
collection,
id: docId,
path,
streaming,
closeStream,
...actions
};
return proxify(moduleInstance, {
data: () => getDataFromDataStore(moduleConfig, globalConfig, collectionPath, docId),
exists: () => getExistsFromDataStore(globalConfig, collectionPath, docId)
});
}
// src/helpers/configHelpers.ts
var import_merge_anything2 = require("merge-anything");
function defaultsGlobalConfig(config) {
const defaults = {
localStoreName: "",
stores: {},
executionOrder: {
read: [],
write: []
},
onError: "revert",
on: {},
modifyPayloadOn: {},
modifyReadResponseOn: {}
};
const merged = (0, import_merge_anything2.merge)(defaults, config);
return merged;
}
// src/Magnetar.ts
function Magnetar(magnetarConfig) {
const globalConfig = defaultsGlobalConfig(magnetarConfig);
const collectionNames = /* @__PURE__ */ new Set();
const writeLockMap = /* @__PURE__ */ new Map();
const closeStreamFnMap = /* @__PURE__ */ new Map();
const streamingPromiseMap = /* @__PURE__ */ new Map();
const fetchPromiseMap = /* @__PURE__ */ new Map();
const fetchMetaMap = /* @__PURE__ */ new Map();
async function clearAllData(options) {
for (const collectionName of collectionNames) {
if (options?.exclude?.includes(collectionName))
continue;
collection(collectionName).data?.clear();
}
}
async function _closeAllStreams(options) {
for (const collectionName of collectionNames) {
if (options?.exclude?.includes(collectionName))
continue;
collection(collectionName).closeAllStreams();
}
}
function getModuleInstance(modulePath, moduleConfig = {}, moduleType, docFn, collectionFn) {
throwIfInvalidModulePath(modulePath, moduleType);
const [collectionPath, docId] = getCollectionPathDocIdEntry(modulePath);
collectionNames.add(collectionPath);
const pathFilterIdentifier = (0, import_types3.getPathFilterIdentifier)(modulePath, moduleConfig);
const fetchPromises = (0, import_getorset_anything2.mapGetOrSet)(
fetchPromiseMap,
pathFilterIdentifier,
() => /* @__PURE__ */ new Map()
);
const pathWhereOrderByIdentifier = (0, import_types3.getPathWhereOrderByIdentifier)(modulePath, moduleConfig);
const fetchMeta = {
get: () => fetchMetaMap.get(pathWhereOrderByIdentifier) || { reachedEnd: false, cursor: void 0 },
set: (payload) => fetchMetaMap.set(pathWhereOrderByIdentifier, payload)
};
function cacheStream(closeStreamFn, streamingPromise) {
closeStreamFnMap.set(pathFilterIdentifier, closeStreamFn);
streamingPromiseMap.set(pathFilterIdentifier, streamingPromise);
}
function streaming() {
return streamingPromiseMap.get(pathFilterIdentifier) || null;
}
function closeStream() {
const closeStreamFn = closeStreamFnMap.get(pathFilterIdentifier);
if (closeStreamFn) {
closeStreamFn();
setTimeout(() => {
streamingPromiseMap.delete(pathFilterIdentifier);
closeStreamFnMap.delete(pathFilterIdentifier);
});
}
}
function closeAllStreams() {
for (const [identifier, closeStreamFn] of closeStreamFnMap) {
const openStreamPath = identifier.split(import_types3.MODULE_IDENTIFIER_SPLIT)[0];
if (openStreamPath === modulePath || openStreamPath.startsWith(modulePath + "/")) {
closeStreamFn();
}
}
}
const streamAndFetchPromises = {
writeLockMap,
fetchPromises,
cacheStream,
streaming,
closeStream,
closeAllStreams
};
if (moduleType === "doc" && (0, import_is_what7.isString)(docId)) {
return createDocWithContext(
[collectionPath, docId],
moduleConfig,
globalConfig,
docFn,
collectionFn,
streamAndFetchPromises
);
}
return createCollectionWithContext(
collectionPath,
moduleConfig,
globalConfig,
docFn,
collectionFn,
streamAndFetchPromises,
fetchMeta
);
}
function collection(modulePath, moduleConfig = {}) {
return getModuleInstance(modulePath, moduleConfig, "collection", doc, collection);
}
function doc(modulePath, moduleConfig = {}) {
return getModuleInstance(modulePath, moduleConfig, "doc", doc, collection);
}
const instance = {
globalConfig,
collection,
doc,
clearAllData,
closeAllStreams: _closeAllStreams
};
return instance;
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
Magnetar,
getCollectionPathDocIdEntry,
getCollectionWriteLocks,
...require("@magnetarjs/types")
});
export * from '@magnetarjs/types';
export * from './Magnetar.js';
export * from './helpers/pathHelpers.js';
{
"name": "@magnetarjs/core",
"version": "0.20.1",
"version": "1.0.1",
"type": "module",
"sideEffects": false,
"description": "Magnetar core library.",
"main": "dist/index.js",
"module": "dist/index.mjs",
"types": "dist/index.d.ts",
"exports": {
".": {
"import": "./dist/index.mjs",
"default": "./dist/index.js"
}
".": "./dist/index.js"
},
"engines": {
"node": ">=18"
},
"files": [

@@ -23,11 +21,8 @@ "dist"

"dependencies": {
"getorset-anything": "^0.0.5",
"is-what": "^4.1.16",
"getorset-anything": "^0.1.0",
"is-what": "^5.0.0",
"merge-anything": "^5.1.7",
"@magnetarjs/utils": "0.20.1",
"@magnetarjs/types": "0.20.1"
"@magnetarjs/types": "1.0.1",
"@magnetarjs/utils": "1.0.1"
},
"devDependencies": {
"@magnetarjs/test-utils": "0.20.1"
},
"keywords": [

@@ -65,19 +60,8 @@ "vuex-easy-firestore",

},
"ava": {
"extensions": [
"ts"
],
"require": [
"esbuild-register"
],
"timeout": "60s"
},
"scripts": {
"typecheck": "tsc --noEmit",
"build": "tsup src/index.ts --clean --format esm,cjs --dts",
"build": "del-cli dist && tsc",
"dev": "pnpm build --watch",
"test-and-build": "npm run test && npm run build",
"test": "ava",
"test--only": "ava --match='*only:*'"
"test": "vitest run"
}
}
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