@oada/list-lib
Advanced tools
Comparing version 2.1.7 to 2.1.8
222
lib/index.js
"use strict"; | ||
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, privateMap, value) { | ||
if (!privateMap.has(receiver)) { | ||
throw new TypeError("attempted to set private field on non-instance"); | ||
} | ||
privateMap.set(receiver, value); | ||
return value; | ||
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { | ||
if (kind === "m") throw new TypeError("Private method is not writable"); | ||
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); | ||
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); | ||
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; | ||
}; | ||
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, privateMap) { | ||
if (!privateMap.has(receiver)) { | ||
throw new TypeError("attempted to get private field on non-instance"); | ||
} | ||
return privateMap.get(receiver); | ||
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) { | ||
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); | ||
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); | ||
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); | ||
}; | ||
@@ -18,3 +16,3 @@ var __importDefault = (this && this.__importDefault) || function (mod) { | ||
}; | ||
var _resume, _conn, _id_1, _assertItem, _meta, _onAddItem, _onChangeItem, _onItem, _onRemoveItem, _onNewList, _onDeleteList, _getItemState; | ||
var _ListWatch_resume, _ListWatch_conn, _ListWatch_id, _ListWatch_assertItem, _ListWatch_meta, _ListWatch_onAddItem, _ListWatch_onChangeItem, _ListWatch_onItem, _ListWatch_onRemoveItem, _ListWatch_onNewList, _ListWatch_onDeleteList, _ListWatch_getItemState; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -47,3 +45,3 @@ exports.ListWatch = exports.pathFromTree = exports.ItemState = void 0; | ||
function assume(id) { | ||
warn(`Assuming item(s) ${id} is ${state}`); | ||
warn('Assuming state %s for item(s) %s', state, id); | ||
if (Array.isArray(id)) { | ||
@@ -109,3 +107,3 @@ const ids = id; | ||
// TODO: Actually handle the list being deleted (redo watch?) | ||
error(`Unhandled delete of list ${path}`); | ||
error('Unhandled delete of list %s', path); | ||
process.exit(); | ||
@@ -115,28 +113,28 @@ }, | ||
getItemState = ListWatch.AssumeNew, }) { | ||
_resume.set(this, void 0); | ||
_conn.set(this, void 0); | ||
_id_1.set(this, void 0); | ||
_assertItem.set(this, void 0); | ||
_ListWatch_resume.set(this, void 0); | ||
_ListWatch_conn.set(this, void 0); | ||
_ListWatch_id.set(this, void 0); | ||
_ListWatch_assertItem.set(this, void 0); | ||
// _meta stuff | ||
_meta.set(this, void 0); | ||
_ListWatch_meta.set(this, void 0); | ||
// Callbacks | ||
_onAddItem.set(this, void 0); | ||
_onChangeItem.set(this, void 0); | ||
_onItem.set(this, void 0); | ||
_onRemoveItem.set(this, void 0); | ||
_onNewList.set(this, void 0); | ||
_onDeleteList.set(this, void 0); | ||
_getItemState.set(this, void 0); | ||
_ListWatch_onAddItem.set(this, void 0); | ||
_ListWatch_onChangeItem.set(this, void 0); | ||
_ListWatch_onItem.set(this, void 0); | ||
_ListWatch_onRemoveItem.set(this, void 0); | ||
_ListWatch_onNewList.set(this, void 0); | ||
_ListWatch_onDeleteList.set(this, void 0); | ||
_ListWatch_getItemState.set(this, void 0); | ||
this.path = path; | ||
this.tree = tree; | ||
this.name = name; | ||
__classPrivateFieldSet(this, _resume, resume); | ||
__classPrivateFieldSet(this, _conn, conn); | ||
__classPrivateFieldSet(this, _assertItem, assertItem); | ||
__classPrivateFieldSet(this, _onAddItem, onAddItem); | ||
__classPrivateFieldSet(this, _onChangeItem, onChangeItem); | ||
__classPrivateFieldSet(this, _onItem, onItem); | ||
__classPrivateFieldSet(this, _onRemoveItem, onRemoveItem); | ||
__classPrivateFieldSet(this, _onDeleteList, onDeleteList); | ||
__classPrivateFieldSet(this, _getItemState, getItemState); | ||
__classPrivateFieldSet(this, _ListWatch_resume, resume, "f"); | ||
__classPrivateFieldSet(this, _ListWatch_conn, conn, "f"); | ||
__classPrivateFieldSet(this, _ListWatch_assertItem, assertItem, "f"); | ||
__classPrivateFieldSet(this, _ListWatch_onAddItem, onAddItem, "f"); | ||
__classPrivateFieldSet(this, _ListWatch_onChangeItem, onChangeItem, "f"); | ||
__classPrivateFieldSet(this, _ListWatch_onItem, onItem, "f"); | ||
__classPrivateFieldSet(this, _ListWatch_onRemoveItem, onRemoveItem, "f"); | ||
__classPrivateFieldSet(this, _ListWatch_onDeleteList, onDeleteList, "f"); | ||
__classPrivateFieldSet(this, _ListWatch_getItemState, getItemState, "f"); | ||
if (itemsPath) { | ||
@@ -156,7 +154,7 @@ this.itemsPath = itemsPath; | ||
if (onNewList) { | ||
__classPrivateFieldSet(this, _onNewList, onNewList); | ||
__classPrivateFieldSet(this, _ListWatch_onNewList, onNewList, "f"); | ||
} | ||
else { | ||
// If no callback provided, ask client for states of pre-existing items | ||
__classPrivateFieldSet(this, _onNewList, (ids) => { | ||
__classPrivateFieldSet(this, _ListWatch_onNewList, (ids) => { | ||
return bluebird_1.default.map(ids, (id) => { | ||
@@ -167,15 +165,15 @@ try { | ||
catch (err) { | ||
error('Error getting item state: %O', err); | ||
error(err, 'Error getting item state'); | ||
} | ||
}); | ||
}); | ||
}, "f"); | ||
} | ||
__classPrivateFieldSet(this, _meta, new Metadata_1.Metadata({ | ||
__classPrivateFieldSet(this, _ListWatch_meta, new Metadata_1.Metadata({ | ||
// Don't persist metdata if service does not "resume" | ||
//persistInterval: this.#resume ? persistInterval : 0, | ||
conn: __classPrivateFieldGet(this, _resume) ? __classPrivateFieldGet(this, _conn) : undefined, | ||
conn: __classPrivateFieldGet(this, _ListWatch_resume, "f") ? __classPrivateFieldGet(this, _ListWatch_conn, "f") : undefined, | ||
path, | ||
tree, | ||
name, | ||
})); | ||
}), "f"); | ||
this.initialize().catch(error); | ||
@@ -196,3 +194,3 @@ } | ||
const { path } = this; | ||
const conn = __classPrivateFieldGet(this, _conn); | ||
const conn = __classPrivateFieldGet(this, _ListWatch_conn, "f"); | ||
const { data: list } = (await conn.get({ path })); | ||
@@ -204,3 +202,3 @@ //const items = Object.keys(list).filter((k) => !k.match(/^_/)); | ||
try { | ||
if (!all && __classPrivateFieldGet(this, _meta).handled(id)) { | ||
if (!all && __classPrivateFieldGet(this, _ListWatch_meta, "f").handled(id)) { | ||
// We think this item is handled | ||
@@ -225,12 +223,12 @@ return; | ||
// Needed because TS is weird about asserts... | ||
const assertItem = __classPrivateFieldGet(this, _assertItem); | ||
if (!stateCBnoItem(__classPrivateFieldGet(this, _getItemState))) { | ||
const { data: item } = await __classPrivateFieldGet(this, _conn).get({ | ||
const assertItem = __classPrivateFieldGet(this, _ListWatch_assertItem, "f"); | ||
if (!stateCBnoItem(__classPrivateFieldGet(this, _ListWatch_getItemState, "f"))) { | ||
const { data: item } = await __classPrivateFieldGet(this, _ListWatch_conn, "f").get({ | ||
path: path_1.join(this.path, id), | ||
}); | ||
assertItem(item); | ||
return __classPrivateFieldGet(this, _getItemState).call(this, id, item); | ||
return __classPrivateFieldGet(this, _ListWatch_getItemState, "f").call(this, id, item); | ||
} | ||
else { | ||
return __classPrivateFieldGet(this, _getItemState).call(this, id); | ||
return __classPrivateFieldGet(this, _ListWatch_getItemState, "f").call(this, id); | ||
} | ||
@@ -242,3 +240,3 @@ } | ||
async stop() { | ||
await __classPrivateFieldGet(this, _conn).unwatch(__classPrivateFieldGet(this, _id_1)); | ||
await __classPrivateFieldGet(this, _ListWatch_conn, "f").unwatch(__classPrivateFieldGet(this, _ListWatch_id, "f")); | ||
await this.persistMeta(); | ||
@@ -258,4 +256,4 @@ //this.#meta.stop(); | ||
// Needed because TS is weird about asserts... | ||
const assertItem = __classPrivateFieldGet(this, _assertItem); | ||
info(`Detected new item ${id} in ${path}, rev ${rev}`); | ||
const assertItem = __classPrivateFieldGet(this, _ListWatch_assertItem, "f"); | ||
info('Detected new item %s in %s, rev %s', id, path, rev); | ||
const { _rev } = item; | ||
@@ -265,5 +263,5 @@ assertItem(item); | ||
// Double check this is a new item? | ||
if (!((_a = (await __classPrivateFieldGet(this, _meta).handled(id))) === null || _a === void 0 ? void 0 : _a.onAddItem)) { | ||
await (__classPrivateFieldGet(this, _onAddItem) && __classPrivateFieldGet(this, _onAddItem).call(this, item, id)); | ||
await __classPrivateFieldGet(this, _meta).setHandled(id, { onAddItem: { rev: _rev + '' } }); | ||
if (!((_a = (await __classPrivateFieldGet(this, _ListWatch_meta, "f").handled(id))) === null || _a === void 0 ? void 0 : _a.onAddItem)) { | ||
await (__classPrivateFieldGet(this, _ListWatch_onAddItem, "f") && __classPrivateFieldGet(this, _ListWatch_onAddItem, "f").call(this, item, id)); | ||
await __classPrivateFieldGet(this, _ListWatch_meta, "f").setHandled(id, { onAddItem: { rev: _rev + '' } }); | ||
} | ||
@@ -276,6 +274,6 @@ } | ||
// Double check this item is actually newer than last time | ||
if (+_rev > +((_d = (_c = (_b = (await __classPrivateFieldGet(this, _meta).handled(id))) === null || _b === void 0 ? void 0 : _b.onItem) === null || _c === void 0 ? void 0 : _c.rev) !== null && _d !== void 0 ? _d : 0)) { | ||
if (+_rev > +((_d = (_c = (_b = (await __classPrivateFieldGet(this, _ListWatch_meta, "f").handled(id))) === null || _b === void 0 ? void 0 : _b.onItem) === null || _c === void 0 ? void 0 : _c.rev) !== null && _d !== void 0 ? _d : 0)) { | ||
// TODO: Why doesn't this.#onItem?.() work? | ||
await (__classPrivateFieldGet(this, _onItem) && __classPrivateFieldGet(this, _onItem).call(this, item, id)); | ||
await __classPrivateFieldGet(this, _meta).setHandled(id, { onItem: { rev: _rev + '' } }); | ||
await (__classPrivateFieldGet(this, _ListWatch_onItem, "f") && __classPrivateFieldGet(this, _ListWatch_onItem, "f").call(this, item, id)); | ||
await __classPrivateFieldGet(this, _ListWatch_meta, "f").setHandled(id, { onItem: { rev: _rev + '' } }); | ||
} | ||
@@ -286,15 +284,15 @@ } | ||
const { path } = this; | ||
const conn = __classPrivateFieldGet(this, _conn); | ||
const conn = __classPrivateFieldGet(this, _ListWatch_conn, "f"); | ||
const rev = change.body._rev; | ||
// TODO: How best to handle change to a descendant of an item? | ||
info(`Detected change to item ${id} in ${path}, rev ${rev}`); | ||
info('Detected change to item %s in %s, rev %s', id, path, rev); | ||
const { _rev } = change.body; | ||
try { | ||
await (__classPrivateFieldGet(this, _onChangeItem) && __classPrivateFieldGet(this, _onChangeItem).call(this, change, id)); | ||
await __classPrivateFieldGet(this, _meta).setHandled(id, { onChangeItem: { rev: _rev + '' } }); | ||
await (__classPrivateFieldGet(this, _ListWatch_onChangeItem, "f") && __classPrivateFieldGet(this, _ListWatch_onChangeItem, "f").call(this, change, id)); | ||
await __classPrivateFieldGet(this, _ListWatch_meta, "f").setHandled(id, { onChangeItem: { rev: _rev + '' } }); | ||
} | ||
finally { | ||
if (__classPrivateFieldGet(this, _onItem)) { | ||
if (__classPrivateFieldGet(this, _ListWatch_onItem, "f")) { | ||
// Needed because TS is weird about asserts... | ||
const assertItem = __classPrivateFieldGet(this, _assertItem); | ||
const assertItem = __classPrivateFieldGet(this, _ListWatch_assertItem, "f"); | ||
const { data: item } = await conn.get({ | ||
@@ -304,4 +302,4 @@ path: path_1.join(path, id), | ||
assertItem(item); | ||
await __classPrivateFieldGet(this, _onItem).call(this, item, id); | ||
await __classPrivateFieldGet(this, _meta).setHandled(id, { onItem: { rev: _rev + '' } }); | ||
await __classPrivateFieldGet(this, _ListWatch_onItem, "f").call(this, item, id); | ||
await __classPrivateFieldGet(this, _ListWatch_meta, "f").setHandled(id, { onItem: { rev: _rev + '' } }); | ||
} | ||
@@ -312,3 +310,3 @@ } | ||
const { path } = this; | ||
const conn = __classPrivateFieldGet(this, _conn); | ||
const conn = __classPrivateFieldGet(this, _ListWatch_conn, "f"); | ||
const rev = list._rev; | ||
@@ -318,3 +316,3 @@ // Ignore _ keys of OADA | ||
const items = getListItems(list, this.itemsPath); | ||
trace(`handleListChange: have items = `, items); | ||
trace(items, 'handleListChange'); | ||
switch (type) { | ||
@@ -324,5 +322,5 @@ case 'merge': | ||
try { | ||
trace('handleListChange: Processing item ', id); | ||
trace('handleListChange: Processing item %s', id); | ||
const lchange = json_pointer_1.default.get(list, id); | ||
trace('handleListChange: lchange = ', lchange); | ||
trace(lchange, 'handleListChange: lchange'); | ||
// If there is an _id this is a new link in the list right? | ||
@@ -338,3 +336,3 @@ if (lchange._id) { | ||
// TODO: What should we do now?? | ||
trace(`Ignoring non-link key added to list ${path}, rev ${rev}`); | ||
trace('Ignoring non-link key added to list %s, rev %s', path, rev); | ||
} | ||
@@ -344,3 +342,3 @@ } | ||
// Log error with this item but continue map over other items | ||
error(`Error processing change for ${id} at ${path}, rev ${rev}: %O`, err); | ||
error(err, `Error processing change for ${id} at ${path}, rev ${rev}`); | ||
} | ||
@@ -354,9 +352,9 @@ }); | ||
if (lchange === null) { | ||
info(`Detected removal of item ${id} from ${path}, rev ${rev}`); | ||
info('Detected removal of item %s from %s, rev %s', id, path, rev); | ||
try { | ||
await (__classPrivateFieldGet(this, _onRemoveItem) && __classPrivateFieldGet(this, _onRemoveItem).call(this, id)); | ||
await (__classPrivateFieldGet(this, _ListWatch_onRemoveItem, "f") && __classPrivateFieldGet(this, _ListWatch_onRemoveItem, "f").call(this, id)); | ||
} | ||
finally { | ||
// Mark for delete? | ||
await __classPrivateFieldGet(this, _meta).setHandled(id, undefined); | ||
await __classPrivateFieldGet(this, _ListWatch_meta, "f").setHandled(id, undefined); | ||
} | ||
@@ -366,3 +364,3 @@ } | ||
// TODO: What does this mean?? | ||
trace(`Ignoring non-link key added to list ${path}, rev ${rev}`); | ||
trace('Ignoring non-link key added to list %s, rev %s', path, rev); | ||
} | ||
@@ -372,3 +370,3 @@ } | ||
// Log error with this item but continue map over other items | ||
error(`Error processing change for ${id} at ${path}, rev ${rev}: %O`, err); | ||
error(err, `Error processing change for ${id} at ${path}, rev ${rev}`); | ||
} | ||
@@ -387,3 +385,3 @@ }); | ||
const { path } = this; | ||
const { rev } = __classPrivateFieldGet(this, _meta); | ||
const { rev } = __classPrivateFieldGet(this, _ListWatch_meta, "f"); | ||
const _ids = Array.isArray(ids) ? ids : [ids]; | ||
@@ -397,3 +395,3 @@ const _states = (Array.isArray(states) ? states : [states]); | ||
{ | ||
const { data: item } = (await __classPrivateFieldGet(this, _conn).get({ | ||
const { data: item } = (await __classPrivateFieldGet(this, _ListWatch_conn, "f").get({ | ||
path: path_1.join(path, id), | ||
@@ -406,3 +404,3 @@ })); | ||
{ | ||
const { data: item } = await __classPrivateFieldGet(this, _conn).get({ | ||
const { data: item } = await __classPrivateFieldGet(this, _ListWatch_conn, "f").get({ | ||
path: path_1.join(path, id), | ||
@@ -421,5 +419,5 @@ }); | ||
case Options_1.ItemState.Handled: | ||
info(`Recoding item ${id} as handled for ${path}`); | ||
info('Recording item %s as handled for %s', id, path); | ||
// Mark handled for all callbacks? | ||
await __classPrivateFieldGet(this, _meta).setHandled(id, { | ||
await __classPrivateFieldGet(this, _ListWatch_meta, "f").setHandled(id, { | ||
onAddItem: { rev }, | ||
@@ -434,3 +432,3 @@ onItem: { rev }, | ||
catch (err) { | ||
error('Error processing item state "%s" for item %s: %O', state, id, err); | ||
error(err, `Error processing item state "${state}" for item ${id}`); | ||
} | ||
@@ -444,4 +442,4 @@ }); | ||
const { path, tree } = this; | ||
const conn = __classPrivateFieldGet(this, _conn); | ||
info(`Ensuring ${path} exists`); | ||
const conn = __classPrivateFieldGet(this, _ListWatch_conn, "f"); | ||
info('Ensuring %s exists', path); | ||
try { | ||
@@ -454,3 +452,3 @@ await conn.head({ path }); | ||
await conn.put({ path, tree, data: {} }); | ||
trace(`Created ${path} because it did not exist`); | ||
trace('Created %s because it did not exist', path); | ||
} | ||
@@ -463,3 +461,3 @@ else { | ||
// TODO: Clean up control flow to not need this? | ||
const currentItemsNew = !(await __classPrivateFieldGet(this, _meta).init()) || !__classPrivateFieldGet(this, _resume); | ||
const currentItemsNew = !(await __classPrivateFieldGet(this, _ListWatch_meta, "f").init()) || !__classPrivateFieldGet(this, _ListWatch_resume, "f"); | ||
if (currentItemsNew) { | ||
@@ -475,3 +473,3 @@ trace('Treating current list items as new items'); | ||
trace('Calling onNewList'); | ||
const states = await __classPrivateFieldGet(this, _onNewList).call(this, items); | ||
const states = await __classPrivateFieldGet(this, _ListWatch_onNewList, "f").call(this, items); | ||
// Set the states | ||
@@ -482,10 +480,10 @@ trace('Updating item states based on callback result'); | ||
// Setup watch on the path | ||
if (__classPrivateFieldGet(this, _resume)) { | ||
trace('Resuming watch from rev %d', __classPrivateFieldGet(this, _meta).rev); | ||
if (__classPrivateFieldGet(this, _ListWatch_resume, "f")) { | ||
trace('Resuming watch from rev %s', __classPrivateFieldGet(this, _ListWatch_meta, "f").rev); | ||
} | ||
// Queue to handle changes in order | ||
const changeQueue = new p_queue_1.default({ concurrency: 1 }); | ||
__classPrivateFieldSet(this, _id_1, await conn.watch({ | ||
__classPrivateFieldSet(this, _ListWatch_id, await conn.watch({ | ||
path, | ||
rev: __classPrivateFieldGet(this, _resume) ? __classPrivateFieldGet(this, _meta).rev : undefined, | ||
rev: __classPrivateFieldGet(this, _ListWatch_resume, "f") ? __classPrivateFieldGet(this, _ListWatch_meta, "f").rev : undefined, | ||
type: 'tree', | ||
@@ -497,15 +495,12 @@ watchCallback: (changes) => changeQueue.add(async () => { | ||
// TODO: Better way than just looping through them all? | ||
await bluebird_1.default.each(changes, async ({ type, path: changePath, body, ...ctx }) => { | ||
await bluebird_1.default.each(changes, async (change) => { | ||
const { type, path: changePath, body, ...ctx } = change; | ||
if (body === null && type === 'delete' && changePath === '') { | ||
// The list itself was deleted | ||
warn(`Detected delete of list ${path}`); | ||
await __classPrivateFieldGet(this, _onDeleteList).call(this); | ||
warn('Detected delete of list %s', path); | ||
await __classPrivateFieldGet(this, _ListWatch_onDeleteList, "f").call(this); | ||
return; | ||
} | ||
const rev = body._rev; | ||
trace(`Received change to ${changePath}: %O`, { | ||
type, | ||
body, | ||
...ctx, | ||
}); | ||
trace(change, 'Received change'); | ||
let itemsFound = !!changePath; | ||
@@ -516,4 +511,6 @@ let listChange = body; | ||
if (changePath) { | ||
// In order to decide if this change was to the list or to an item, need to check if itemsPath | ||
// matches the changePath: if it does, it is to an item. If it doesn't, it's probably to the list. | ||
// To decide if this change was to the list or to an item, | ||
// need to check if itemsPath matches the changePath: | ||
// if it does, it is to an item. | ||
// If it doesn't, it's probably to the list. | ||
// Reconstruct change to list? | ||
@@ -523,3 +520,4 @@ const changeObj = {}; | ||
if (this.itemsPath) { | ||
json_pointer_1.default.set(changeObj, changePath, true); // just put true here for now to check if path matches | ||
// just put true here for now to check if path matches | ||
json_pointer_1.default.set(changeObj, changePath, true); | ||
const pathmatches = jsonpath_plus_1.JSONPath({ | ||
@@ -531,3 +529,3 @@ resultType: 'pointer', | ||
}); | ||
if (pathmatches && pathmatches.length === 0) { | ||
if ((pathmatches === null || pathmatches === void 0 ? void 0 : pathmatches.length) === 0) { | ||
// if it does not match, this must be above the items | ||
@@ -556,3 +554,3 @@ isListChange = true; | ||
if (!body._rev) { | ||
warn(`Ignoring unexpected (as in the body does not have a _rev) change: %O`, change); | ||
warn(change, 'Ignoring unexpected (as in the body does not have a _rev) change'); | ||
return; | ||
@@ -569,3 +567,3 @@ } | ||
} | ||
trace(`Change was to the list itself because changePath is empty, calling handleListChange`); | ||
trace('Change was to the list itself because changePath is empty, calling handleListChange'); | ||
// The change was to the list itself | ||
@@ -576,15 +574,15 @@ itemsFound = | ||
catch (err) { | ||
error(`Error processing change at ${path}, rev ${rev}: %O`, err); | ||
error(err, `Error processing change at ${path}, rev ${rev}`); | ||
} | ||
}); | ||
if (__classPrivateFieldGet(this, _resume)) { | ||
trace(`Received change to root of list, updating handled rev in our _meta records`); | ||
__classPrivateFieldGet(this, _meta).rev = ((_a = rootChange.body) === null || _a === void 0 ? void 0 : _a._rev) + ''; | ||
if (__classPrivateFieldGet(this, _ListWatch_resume, "f")) { | ||
trace('Received change to root of list, updating handled rev in our _meta records'); | ||
__classPrivateFieldGet(this, _ListWatch_meta, "f").rev = ((_a = rootChange.body) === null || _a === void 0 ? void 0 : _a._rev) + ''; | ||
} | ||
}), | ||
})); | ||
}), "f"); | ||
} | ||
} | ||
exports.ListWatch = ListWatch; | ||
_resume = new WeakMap(), _conn = new WeakMap(), _id_1 = new WeakMap(), _assertItem = new WeakMap(), _meta = new WeakMap(), _onAddItem = new WeakMap(), _onChangeItem = new WeakMap(), _onItem = new WeakMap(), _onRemoveItem = new WeakMap(), _onNewList = new WeakMap(), _onDeleteList = new WeakMap(), _getItemState = new WeakMap(); | ||
_ListWatch_resume = new WeakMap(), _ListWatch_conn = new WeakMap(), _ListWatch_id = new WeakMap(), _ListWatch_assertItem = new WeakMap(), _ListWatch_meta = new WeakMap(), _ListWatch_onAddItem = new WeakMap(), _ListWatch_onChangeItem = new WeakMap(), _ListWatch_onItem = new WeakMap(), _ListWatch_onRemoveItem = new WeakMap(), _ListWatch_onNewList = new WeakMap(), _ListWatch_onDeleteList = new WeakMap(), _ListWatch_getItemState = new WeakMap(); | ||
/** | ||
@@ -591,0 +589,0 @@ * Callback to make ListWatch consider every `Item` new |
"use strict"; | ||
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, privateMap, value) { | ||
if (!privateMap.has(receiver)) { | ||
throw new TypeError("attempted to set private field on non-instance"); | ||
} | ||
privateMap.set(receiver, value); | ||
return value; | ||
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { | ||
if (kind === "m") throw new TypeError("Private method is not writable"); | ||
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); | ||
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); | ||
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; | ||
}; | ||
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, privateMap) { | ||
if (!privateMap.has(receiver)) { | ||
throw new TypeError("attempted to get private field on non-instance"); | ||
} | ||
return privateMap.get(receiver); | ||
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) { | ||
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); | ||
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); | ||
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); | ||
}; | ||
@@ -18,3 +16,3 @@ var __importDefault = (this && this.__importDefault) || function (mod) { | ||
}; | ||
var _rev, _conn, _path, _tree, _timeout, _done, _wait; | ||
var _Metadata_rev, _Metadata_conn, _Metadata_path, _Metadata_tree, _Metadata_timeout, _Metadata_done, _Metadata_wait; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -38,18 +36,18 @@ exports.Metadata = void 0; | ||
*/ | ||
_rev.set(this, '0'); | ||
_Metadata_rev.set(this, void 0); | ||
// Where to store state | ||
_conn.set(this, void 0); | ||
_path.set(this, void 0); | ||
_tree.set(this, void 0); | ||
_timeout.set(this, void 0); | ||
_Metadata_conn.set(this, void 0); | ||
_Metadata_path.set(this, void 0); | ||
_Metadata_tree.set(this, void 0); | ||
_Metadata_timeout.set(this, void 0); | ||
// Init stuff? | ||
_done.set(this, void 0); | ||
_wait.set(this, void 0); | ||
__classPrivateFieldSet(this, _conn, conn); | ||
__classPrivateFieldSet(this, _path, path_1.join(path, '_meta', Metadata.META_KEY, name)); | ||
__classPrivateFieldSet(this, _tree, clone_deep_1.default(tree)); | ||
if (__classPrivateFieldGet(this, _tree)) { | ||
_Metadata_done.set(this, void 0); | ||
_Metadata_wait.set(this, void 0); | ||
__classPrivateFieldSet(this, _Metadata_conn, conn, "f"); | ||
__classPrivateFieldSet(this, _Metadata_path, path_1.join(path, '_meta', Metadata.META_KEY, name), "f"); | ||
__classPrivateFieldSet(this, _Metadata_tree, clone_deep_1.default(tree), "f"); | ||
if (__classPrivateFieldGet(this, _Metadata_tree, "f")) { | ||
// Replicate list tree under handled key? | ||
const listTree = clone_deep_1.default(json_pointer_1.default.get(__classPrivateFieldGet(this, _tree), path)); | ||
json_pointer_1.default.set(__classPrivateFieldGet(this, _tree), __classPrivateFieldGet(this, _path), { | ||
const listTree = clone_deep_1.default(json_pointer_1.default.get(__classPrivateFieldGet(this, _Metadata_tree, "f"), path)); | ||
json_pointer_1.default.set(__classPrivateFieldGet(this, _Metadata_tree, "f"), __classPrivateFieldGet(this, _Metadata_path, "f"), { | ||
_type: 'application/json', | ||
@@ -61,4 +59,4 @@ handled: listTree, | ||
// Make up a tree? idk man | ||
__classPrivateFieldSet(this, _tree, {}); | ||
json_pointer_1.default.set(__classPrivateFieldGet(this, _tree), __classPrivateFieldGet(this, _path), { | ||
__classPrivateFieldSet(this, _Metadata_tree, {}, "f"); | ||
json_pointer_1.default.set(__classPrivateFieldGet(this, _Metadata_tree, "f"), __classPrivateFieldGet(this, _Metadata_path, "f"), { | ||
_type: 'application/json', | ||
@@ -69,24 +67,28 @@ handled: { '*': {} }, | ||
//console.dir(this.#tree, { depth: null }); | ||
__classPrivateFieldSet(this, _wait, bluebird_1.default.fromCallback((done) => { | ||
__classPrivateFieldSet(this, _done, done); | ||
})); | ||
__classPrivateFieldSet(this, _Metadata_wait, bluebird_1.default.fromCallback((done) => { | ||
__classPrivateFieldSet(this, _Metadata_done, done, "f"); | ||
}), "f"); | ||
// TODO: Use timeouts for all updates? | ||
__classPrivateFieldSet(this, _timeout, setTimeout(async () => { | ||
__classPrivateFieldSet(this, _Metadata_timeout, setTimeout(async () => { | ||
var _a; | ||
await __classPrivateFieldGet(this, _wait); | ||
trace('Recording rev %d', __classPrivateFieldGet(this, _rev)); | ||
__classPrivateFieldSet(this, _wait, Promise.resolve((_a = __classPrivateFieldGet(this, _conn)) === null || _a === void 0 ? void 0 : _a.put({ | ||
path: __classPrivateFieldGet(this, _path), | ||
tree: __classPrivateFieldGet(this, _tree), | ||
data: { rev: __classPrivateFieldGet(this, _rev) }, | ||
}))); | ||
}, 100)); | ||
await __classPrivateFieldGet(this, _Metadata_wait, "f"); | ||
trace('Recording rev %s', __classPrivateFieldGet(this, _Metadata_rev, "f")); | ||
__classPrivateFieldSet(this, _Metadata_wait, Promise.resolve((_a = __classPrivateFieldGet(this, _Metadata_conn, "f")) === null || _a === void 0 ? void 0 : _a.put({ | ||
path: __classPrivateFieldGet(this, _Metadata_path, "f"), | ||
tree: __classPrivateFieldGet(this, _Metadata_tree, "f"), | ||
data: { rev: __classPrivateFieldGet(this, _Metadata_rev, "f") }, | ||
})), "f"); | ||
}, 100), "f"); | ||
} | ||
get rev() { | ||
return __classPrivateFieldGet(this, _rev) + ''; | ||
return __classPrivateFieldGet(this, _Metadata_rev, "f") + ''; | ||
} | ||
set rev(rev) { | ||
if (__classPrivateFieldGet(this, _Metadata_rev, "f") === rev) { | ||
// No need to update | ||
return; | ||
} | ||
trace(`Updating local rev to ${rev}`); | ||
__classPrivateFieldSet(this, _rev, rev); | ||
__classPrivateFieldGet(this, _timeout).refresh(); | ||
__classPrivateFieldSet(this, _Metadata_rev, rev, "f"); | ||
__classPrivateFieldGet(this, _Metadata_timeout, "f").refresh(); | ||
} | ||
@@ -105,5 +107,5 @@ /** | ||
json_pointer_1.default.set(data, `/handled${path}`, item); | ||
await ((_a = __classPrivateFieldGet(this, _conn)) === null || _a === void 0 ? void 0 : _a.put({ | ||
path: __classPrivateFieldGet(this, _path), | ||
tree: __classPrivateFieldGet(this, _tree), | ||
await ((_a = __classPrivateFieldGet(this, _Metadata_conn, "f")) === null || _a === void 0 ? void 0 : _a.put({ | ||
path: __classPrivateFieldGet(this, _Metadata_path, "f"), | ||
tree: __classPrivateFieldGet(this, _Metadata_tree, "f"), | ||
data: data, | ||
@@ -114,3 +116,3 @@ })); | ||
// Unset info? | ||
await ((_b = __classPrivateFieldGet(this, _conn)) === null || _b === void 0 ? void 0 : _b.delete({ path: path_1.join(__classPrivateFieldGet(this, _path), 'handled', path) })); | ||
await ((_b = __classPrivateFieldGet(this, _Metadata_conn, "f")) === null || _b === void 0 ? void 0 : _b.delete({ path: path_1.join(__classPrivateFieldGet(this, _Metadata_path, "f"), 'handled', path) })); | ||
} | ||
@@ -125,8 +127,8 @@ //this.#updated = true; | ||
async handled(path) { | ||
if (!__classPrivateFieldGet(this, _conn)) { | ||
if (!__classPrivateFieldGet(this, _Metadata_conn, "f")) { | ||
return undefined; | ||
} | ||
try { | ||
const { data } = await __classPrivateFieldGet(this, _conn).get({ | ||
path: path_1.join(__classPrivateFieldGet(this, _path), 'handled', path), | ||
const { data } = await __classPrivateFieldGet(this, _Metadata_conn, "f").get({ | ||
path: path_1.join(__classPrivateFieldGet(this, _Metadata_path, "f"), 'handled', path), | ||
}); | ||
@@ -147,5 +149,5 @@ return data; | ||
try { | ||
if (!__classPrivateFieldGet(this, _conn)) { | ||
__classPrivateFieldSet(this, _rev, undefined); | ||
__classPrivateFieldGet(this, _done).call(this); | ||
if (!__classPrivateFieldGet(this, _Metadata_conn, "f")) { | ||
__classPrivateFieldSet(this, _Metadata_rev, undefined, "f"); | ||
__classPrivateFieldGet(this, _Metadata_done, "f").call(this); | ||
return false; | ||
@@ -155,7 +157,7 @@ } | ||
try { | ||
const { data: rev } = await __classPrivateFieldGet(this, _conn).get({ | ||
path: path_1.join(__classPrivateFieldGet(this, _path), 'rev'), | ||
const { data: rev } = await __classPrivateFieldGet(this, _Metadata_conn, "f").get({ | ||
path: path_1.join(__classPrivateFieldGet(this, _Metadata_path, "f"), 'rev'), | ||
}); | ||
__classPrivateFieldSet(this, _rev, rev); | ||
__classPrivateFieldGet(this, _done).call(this); | ||
__classPrivateFieldSet(this, _Metadata_rev, rev, "f"); | ||
__classPrivateFieldGet(this, _Metadata_done, "f").call(this); | ||
return true; | ||
@@ -165,19 +167,19 @@ } | ||
// Create our metadata? | ||
const { headers: { 'content-location': location }, } = await __classPrivateFieldGet(this, _conn).post({ | ||
const { headers: { 'content-location': location }, } = await __classPrivateFieldGet(this, _Metadata_conn, "f").post({ | ||
path: '/resources/', | ||
data: {}, | ||
}); | ||
await __classPrivateFieldGet(this, _conn).put({ | ||
path: __classPrivateFieldGet(this, _path), | ||
tree: __classPrivateFieldGet(this, _tree), | ||
await __classPrivateFieldGet(this, _Metadata_conn, "f").put({ | ||
path: __classPrivateFieldGet(this, _Metadata_path, "f"), | ||
tree: __classPrivateFieldGet(this, _Metadata_tree, "f"), | ||
data: { _id: location.substring(1) }, | ||
}); | ||
await __classPrivateFieldGet(this, _conn).put({ | ||
path: __classPrivateFieldGet(this, _path), | ||
tree: __classPrivateFieldGet(this, _tree), | ||
await __classPrivateFieldGet(this, _Metadata_conn, "f").put({ | ||
path: __classPrivateFieldGet(this, _Metadata_path, "f"), | ||
tree: __classPrivateFieldGet(this, _Metadata_tree, "f"), | ||
data: { | ||
rev: __classPrivateFieldGet(this, _rev), | ||
rev: __classPrivateFieldGet(this, _Metadata_rev, "f"), | ||
}, | ||
}); | ||
__classPrivateFieldGet(this, _done).call(this); | ||
__classPrivateFieldGet(this, _Metadata_done, "f").call(this); | ||
return false; | ||
@@ -187,3 +189,3 @@ } | ||
catch (err) { | ||
__classPrivateFieldGet(this, _done).call(this, err); | ||
__classPrivateFieldGet(this, _Metadata_done, "f").call(this, err); | ||
throw err; | ||
@@ -194,3 +196,3 @@ } | ||
exports.Metadata = Metadata; | ||
_rev = new WeakMap(), _conn = new WeakMap(), _path = new WeakMap(), _tree = new WeakMap(), _timeout = new WeakMap(), _done = new WeakMap(), _wait = new WeakMap(); | ||
_Metadata_rev = new WeakMap(), _Metadata_conn = new WeakMap(), _Metadata_path = new WeakMap(), _Metadata_tree = new WeakMap(), _Metadata_timeout = new WeakMap(), _Metadata_done = new WeakMap(), _Metadata_wait = new WeakMap(); | ||
/** | ||
@@ -197,0 +199,0 @@ * @todo: Where in _meta to keep stuff? |
@@ -46,3 +46,3 @@ "use strict"; | ||
resource_id: 'resources/default:resources_bookmarks_321', | ||
path: '', | ||
path: '/foo', | ||
body: { | ||
@@ -81,3 +81,3 @@ '1e6XB0Hy7XJICbi3nMzCtl4QLpC': { | ||
await cb(change); | ||
await bluebird_1.default.delay(100); | ||
await bluebird_1.default.delay(500); | ||
t.assert(conn.put.calledWithMatch({ | ||
@@ -84,0 +84,0 @@ path: `${path}/_meta/oada-list-lib/${name}`, |
{ | ||
"name": "@oada/list-lib", | ||
"version": "2.1.7", | ||
"version": "2.1.8", | ||
"description": "Library for processing items in an OADA list", | ||
@@ -36,2 +36,3 @@ "main": "lib/index.js", | ||
"typescript": { | ||
"compile": "tsc", | ||
"rewritePaths": { | ||
@@ -43,15 +44,16 @@ "src/": "lib/" | ||
"devDependencies": { | ||
"@ava/typescript": "^1.1.1", | ||
"@tsconfig/node12": "^1.0.7", | ||
"@types/bluebird": "^3.5.32", | ||
"@ava/typescript": "^2.0.0", | ||
"@tsconfig/node12": "^1.0.9", | ||
"@types/bluebird": "^3.5.36", | ||
"@types/clone-deep": "^4.0.1", | ||
"@types/debug": "^4.1.5", | ||
"@types/json-pointer": "^1.0.30", | ||
"@types/node": "^14.14.22", | ||
"@types/debug": "^4.1.7", | ||
"@types/json-pointer": "^1.0.31", | ||
"@types/node": "^14.17.9", | ||
"@types/object-assign-deep": "^0.4.0", | ||
"@types/sinon": "^9.0.10", | ||
"@types/sinon": "^10.0.2", | ||
"@yarnpkg/sdks": "^2.4.1-rc.4", | ||
"ava": "^3.15.0", | ||
"prettier": "^2.2.1", | ||
"sinon": "^9.2.3", | ||
"typescript": "^4.2.0-beta" | ||
"prettier": "^2.3.2", | ||
"sinon": "^11.1.2", | ||
"typescript": "^4.3.5" | ||
}, | ||
@@ -65,5 +67,6 @@ "dependencies": { | ||
"json-pointer": "^0.6.0", | ||
"jsonpath-plus": "^5.0.2", | ||
"jsonpath-plus": "^6.0.1", | ||
"p-queue": "^6.6.2" | ||
} | ||
} | ||
}, | ||
"packageManager": "yarn@3.0.0" | ||
} |
221
src/index.ts
@@ -66,3 +66,3 @@ import { join } from 'path'; | ||
function assume(id: string | readonly string[]) { | ||
warn(`Assuming item(s) ${id} is ${state}`); | ||
warn('Assuming state %s for item(s) %s', state, id); | ||
if (Array.isArray(id)) { | ||
@@ -245,3 +245,3 @@ const ids = id; | ||
// TODO: Actually handle the list being deleted (redo watch?) | ||
error(`Unhandled delete of list ${path}`); | ||
error('Unhandled delete of list %s', path); | ||
process.exit(); | ||
@@ -287,3 +287,3 @@ }, | ||
} catch (err) { | ||
error('Error getting item state: %O', err); | ||
error(err, 'Error getting item state'); | ||
} | ||
@@ -385,3 +385,3 @@ }); | ||
info(`Detected new item ${id} in ${path}, rev ${rev}`); | ||
info('Detected new item %s in %s, rev %s', id, path, rev); | ||
const { _rev } = item; | ||
@@ -417,3 +417,3 @@ assertItem(item); | ||
// TODO: How best to handle change to a descendant of an item? | ||
info(`Detected change to item ${id} in ${path}, rev ${rev}`); | ||
info('Detected change to item %s in %s, rev %s', id, path, rev); | ||
@@ -449,3 +449,3 @@ const { _rev } = change.body; | ||
const items = getListItems(list as List, this.itemsPath); | ||
trace(`handleListChange: have items = `, items); | ||
trace(items, 'handleListChange'); | ||
@@ -456,5 +456,5 @@ switch (type) { | ||
try { | ||
trace('handleListChange: Processing item ', id); | ||
trace('handleListChange: Processing item %s', id); | ||
const lchange = pointer.get(list, id) as Partial<Link>; | ||
trace('handleListChange: lchange = ', lchange); | ||
trace(lchange, 'handleListChange: lchange'); | ||
@@ -472,3 +472,7 @@ // If there is an _id this is a new link in the list right? | ||
// TODO: What should we do now?? | ||
trace(`Ignoring non-link key added to list ${path}, rev ${rev}`); | ||
trace( | ||
'Ignoring non-link key added to list %s, rev %s', | ||
path, | ||
rev | ||
); | ||
} | ||
@@ -478,4 +482,4 @@ } catch (err: unknown) { | ||
error( | ||
`Error processing change for ${id} at ${path}, rev ${rev}: %O`, | ||
err | ||
err, | ||
`Error processing change for ${id} at ${path}, rev ${rev}` | ||
); | ||
@@ -492,3 +496,8 @@ } | ||
if (lchange === null) { | ||
info(`Detected removal of item ${id} from ${path}, rev ${rev}`); | ||
info( | ||
'Detected removal of item %s from %s, rev %s', | ||
id, | ||
path, | ||
rev | ||
); | ||
try { | ||
@@ -502,3 +511,7 @@ await (this.#onRemoveItem && this.#onRemoveItem(id)); | ||
// TODO: What does this mean?? | ||
trace(`Ignoring non-link key added to list ${path}, rev ${rev}`); | ||
trace( | ||
'Ignoring non-link key added to list %s, rev %s', | ||
path, | ||
rev | ||
); | ||
} | ||
@@ -508,4 +521,4 @@ } catch (err: unknown) { | ||
error( | ||
`Error processing change for ${id} at ${path}, rev ${rev}: %O`, | ||
err | ||
err, | ||
`Error processing change for ${id} at ${path}, rev ${rev}` | ||
); | ||
@@ -563,3 +576,3 @@ } | ||
case ItemState.Handled: | ||
info(`Recoding item ${id} as handled for ${path}`); | ||
info('Recording item %s as handled for %s', id, path); | ||
// Mark handled for all callbacks? | ||
@@ -575,8 +588,3 @@ await this.#meta.setHandled(id, { | ||
} catch (err: unknown) { | ||
error( | ||
'Error processing item state "%s" for item %s: %O', | ||
state, | ||
id, | ||
err | ||
); | ||
error(err, `Error processing item state "${state}" for item ${id}`); | ||
} | ||
@@ -593,3 +601,3 @@ }); | ||
info(`Ensuring ${path} exists`); | ||
info('Ensuring %s exists', path); | ||
try { | ||
@@ -601,3 +609,3 @@ await conn.head({ path }); | ||
await conn.put({ path, tree, data: {} }); | ||
trace(`Created ${path} because it did not exist`); | ||
trace('Created %s because it did not exist', path); | ||
} else { | ||
@@ -630,3 +638,3 @@ error(err); | ||
if (this.#resume) { | ||
trace('Resuming watch from rev %d', this.#meta.rev); | ||
trace('Resuming watch from rev %s', this.#meta.rev); | ||
} | ||
@@ -645,99 +653,94 @@ // Queue to handle changes in order | ||
// TODO: Better way than just looping through them all? | ||
await Bluebird.each( | ||
changes, | ||
async ({ type, path: changePath, body, ...ctx }) => { | ||
if (body === null && type === 'delete' && changePath === '') { | ||
// The list itself was deleted | ||
warn(`Detected delete of list ${path}`); | ||
await Bluebird.each(changes, async (change) => { | ||
const { type, path: changePath, body, ...ctx } = change; | ||
await this.#onDeleteList(); | ||
return; | ||
} | ||
if (body === null && type === 'delete' && changePath === '') { | ||
// The list itself was deleted | ||
warn('Detected delete of list %s', path); | ||
const rev = (body as Change['body'])._rev as string; | ||
await this.#onDeleteList(); | ||
return; | ||
} | ||
trace(`Received change to ${changePath}: %O`, { | ||
type, | ||
body, | ||
...ctx, | ||
}); | ||
const rev = (body as Change['body'])._rev as string; | ||
let itemsFound = !!changePath; | ||
let listChange = body as DeepPartial<List>; | ||
try { | ||
// The actual change was to a descendant of the list | ||
if (changePath) { | ||
// In order to decide if this change was to the list or to an item, need to check if itemsPath | ||
// matches the changePath: if it does, it is to an item. If it doesn't, it's probably to the list. | ||
trace(change, 'Received change'); | ||
// Reconstruct change to list? | ||
const changeObj = {}; | ||
let isListChange = false; | ||
if (this.itemsPath) { | ||
pointer.set(changeObj, changePath, true); // just put true here for now to check if path matches | ||
const pathmatches = JSONPath({ | ||
resultType: 'pointer', | ||
path: this.itemsPath, | ||
json: changeObj, | ||
preventEval: true, | ||
}); | ||
if (pathmatches && pathmatches.length === 0) { | ||
// if it does not match, this must be above the items | ||
isListChange = true; | ||
trace( | ||
'Have a write to the list under itemsPath rather than to any of the items' | ||
); | ||
} | ||
} | ||
let itemsFound = !!changePath; | ||
let listChange = body as DeepPartial<List>; | ||
try { | ||
// The actual change was to a descendant of the list | ||
if (changePath) { | ||
// To decide if this change was to the list or to an item, | ||
// need to check if itemsPath matches the changePath: | ||
// if it does, it is to an item. | ||
// If it doesn't, it's probably to the list. | ||
// now put the actual change body in place of the true | ||
pointer.set(changeObj, changePath, body); | ||
// Find items involved in the change | ||
const itemsChanged = getListItems(changeObj, this.itemsPath); | ||
// The change was to items of the list (or their descendants) | ||
if (!isListChange && itemsChanged.length >= 1) { | ||
return Bluebird.map(itemsChanged, (item) => { | ||
const body = pointer.get(changeObj, item); | ||
// Make change start at item instead of the list | ||
const path = changePath.slice(item.length); | ||
const change: Change = { | ||
...ctx, | ||
type, | ||
path, | ||
body, | ||
}; | ||
// Check that it is a resource change? | ||
if (!body._rev) { | ||
warn( | ||
`Ignoring unexpected (as in the body does not have a _rev) change: %O`, | ||
change | ||
); | ||
return; | ||
} | ||
return this.handleItemChange(item, change); | ||
}); | ||
} else { | ||
// The change is between the list and items | ||
// (multiple link levels) | ||
listChange = changeObj; | ||
// Reconstruct change to list? | ||
const changeObj = {}; | ||
let isListChange = false; | ||
if (this.itemsPath) { | ||
// just put true here for now to check if path matches | ||
pointer.set(changeObj, changePath, true); | ||
const pathmatches = JSONPath({ | ||
resultType: 'pointer', | ||
path: this.itemsPath, | ||
json: changeObj, | ||
preventEval: true, | ||
}); | ||
if (pathmatches?.length === 0) { | ||
// if it does not match, this must be above the items | ||
isListChange = true; | ||
trace( | ||
'Have a write to the list under itemsPath rather than to any of the items' | ||
); | ||
} | ||
} | ||
trace( | ||
`Change was to the list itself because changePath is empty, calling handleListChange` | ||
); | ||
// The change was to the list itself | ||
itemsFound = | ||
(await this.handleListChange(listChange, type)) || itemsFound; | ||
} catch (err: unknown) { | ||
error( | ||
`Error processing change at ${path}, rev ${rev}: %O`, | ||
err | ||
); | ||
// now put the actual change body in place of the true | ||
pointer.set(changeObj, changePath, body); | ||
// Find items involved in the change | ||
const itemsChanged = getListItems(changeObj, this.itemsPath); | ||
// The change was to items of the list (or their descendants) | ||
if (!isListChange && itemsChanged.length >= 1) { | ||
return Bluebird.map(itemsChanged, (item) => { | ||
const body = pointer.get(changeObj, item); | ||
// Make change start at item instead of the list | ||
const path = changePath.slice(item.length); | ||
const change: Change = { | ||
...ctx, | ||
type, | ||
path, | ||
body, | ||
}; | ||
// Check that it is a resource change? | ||
if (!body._rev) { | ||
warn( | ||
change, | ||
'Ignoring unexpected (as in the body does not have a _rev) change' | ||
); | ||
return; | ||
} | ||
return this.handleItemChange(item, change); | ||
}); | ||
} else { | ||
// The change is between the list and items | ||
// (multiple link levels) | ||
listChange = changeObj; | ||
} | ||
} | ||
trace( | ||
'Change was to the list itself because changePath is empty, calling handleListChange' | ||
); | ||
// The change was to the list itself | ||
itemsFound = | ||
(await this.handleListChange(listChange, type)) || itemsFound; | ||
} catch (err: unknown) { | ||
error(err, `Error processing change at ${path}, rev ${rev}`); | ||
} | ||
); | ||
}); | ||
if (this.#resume) { | ||
trace( | ||
`Received change to root of list, updating handled rev in our _meta records` | ||
'Received change to root of list, updating handled rev in our _meta records' | ||
); | ||
@@ -744,0 +747,0 @@ this.#meta.rev = (rootChange.body as Resource)?._rev + ''; |
@@ -52,3 +52,3 @@ import test from 'ava'; | ||
resource_id: 'resources/default:resources_bookmarks_321', | ||
path: '', | ||
path: '/foo', | ||
body: { | ||
@@ -94,3 +94,3 @@ '1e6XB0Hy7XJICbi3nMzCtl4QLpC': { | ||
await Bluebird.delay(100); | ||
await Bluebird.delay(500); | ||
@@ -97,0 +97,0 @@ t.assert( |
@@ -54,3 +54,3 @@ import { join } from 'path'; | ||
*/ | ||
#rev? = '0'; | ||
#rev?: string; | ||
@@ -70,2 +70,6 @@ // Where to store state | ||
set rev(rev) { | ||
if (this.#rev === rev) { | ||
// No need to update | ||
return; | ||
} | ||
trace(`Updating local rev to ${rev}`); | ||
@@ -163,3 +167,3 @@ this.#rev = rev; | ||
await this.#wait; | ||
trace('Recording rev %d', this.#rev); | ||
trace('Recording rev %s', this.#rev); | ||
this.#wait = Promise.resolve( | ||
@@ -166,0 +170,0 @@ this.#conn?.put({ |
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
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
144355
42
3040
14
24
+ Addedjsonpath-plus@6.0.1(transitive)
- Removedjsonpath-plus@5.1.0(transitive)
Updatedjsonpath-plus@^6.0.1