Replacing CLS with local-storage, simplified usage which should remove the memory leak permenantly.
This commit is contained in:
parent
a15a265bda
commit
c6d31a856a
|
@ -1,6 +1 @@
|
||||||
module.exports = {
|
module.exports = require("./src/db")
|
||||||
...require("./src/db/utils"),
|
|
||||||
...require("./src/db/constants"),
|
|
||||||
...require("./src/db"),
|
|
||||||
...require("./src/db/views"),
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,650 +0,0 @@
|
||||||
const util = require("util")
|
|
||||||
const assert = require("assert")
|
|
||||||
const wrapEmitter = require("emitter-listener")
|
|
||||||
const async_hooks = require("async_hooks")
|
|
||||||
|
|
||||||
const CONTEXTS_SYMBOL = "cls@contexts"
|
|
||||||
const ERROR_SYMBOL = "error@context"
|
|
||||||
|
|
||||||
const DEBUG_CLS_HOOKED = process.env.DEBUG_CLS_HOOKED
|
|
||||||
|
|
||||||
let currentUid = -1
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
getNamespace: getNamespace,
|
|
||||||
createNamespace: createNamespace,
|
|
||||||
destroyNamespace: destroyNamespace,
|
|
||||||
reset: reset,
|
|
||||||
ERROR_SYMBOL: ERROR_SYMBOL,
|
|
||||||
}
|
|
||||||
|
|
||||||
function Namespace(name) {
|
|
||||||
this.name = name
|
|
||||||
// changed in 2.7: no default context
|
|
||||||
this.active = null
|
|
||||||
this._set = []
|
|
||||||
this.id = null
|
|
||||||
this._contexts = new Map()
|
|
||||||
this._indent = 0
|
|
||||||
this._hook = null
|
|
||||||
}
|
|
||||||
|
|
||||||
Namespace.prototype.set = function set(key, value) {
|
|
||||||
if (!this.active) {
|
|
||||||
throw new Error(
|
|
||||||
"No context available. ns.run() or ns.bind() must be called first."
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
this.active[key] = value
|
|
||||||
|
|
||||||
if (DEBUG_CLS_HOOKED) {
|
|
||||||
const indentStr = " ".repeat(this._indent < 0 ? 0 : this._indent)
|
|
||||||
debug2(
|
|
||||||
indentStr +
|
|
||||||
"CONTEXT-SET KEY:" +
|
|
||||||
key +
|
|
||||||
"=" +
|
|
||||||
value +
|
|
||||||
" in ns:" +
|
|
||||||
this.name +
|
|
||||||
" currentUid:" +
|
|
||||||
currentUid +
|
|
||||||
" active:" +
|
|
||||||
util.inspect(this.active, { showHidden: true, depth: 2, colors: true })
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return value
|
|
||||||
}
|
|
||||||
|
|
||||||
Namespace.prototype.get = function get(key) {
|
|
||||||
if (!this.active) {
|
|
||||||
if (DEBUG_CLS_HOOKED) {
|
|
||||||
const asyncHooksCurrentId = async_hooks.currentId()
|
|
||||||
const triggerId = async_hooks.triggerAsyncId()
|
|
||||||
const indentStr = " ".repeat(this._indent < 0 ? 0 : this._indent)
|
|
||||||
debug2(
|
|
||||||
`${indentStr}CONTEXT-GETTING KEY NO ACTIVE NS: (${this.name}) ${key}=undefined currentUid:${currentUid} asyncHooksCurrentId:${asyncHooksCurrentId} triggerId:${triggerId} len:${this._set.length}`
|
|
||||||
)
|
|
||||||
}
|
|
||||||
return undefined
|
|
||||||
}
|
|
||||||
if (DEBUG_CLS_HOOKED) {
|
|
||||||
const asyncHooksCurrentId = async_hooks.executionAsyncId()
|
|
||||||
const triggerId = async_hooks.triggerAsyncId()
|
|
||||||
const indentStr = " ".repeat(this._indent < 0 ? 0 : this._indent)
|
|
||||||
debug2(
|
|
||||||
indentStr +
|
|
||||||
"CONTEXT-GETTING KEY:" +
|
|
||||||
key +
|
|
||||||
"=" +
|
|
||||||
this.active[key] +
|
|
||||||
" (" +
|
|
||||||
this.name +
|
|
||||||
") currentUid:" +
|
|
||||||
currentUid +
|
|
||||||
" active:" +
|
|
||||||
util.inspect(this.active, { showHidden: true, depth: 2, colors: true })
|
|
||||||
)
|
|
||||||
debug2(
|
|
||||||
`${indentStr}CONTEXT-GETTING KEY: (${this.name}) ${key}=${
|
|
||||||
this.active[key]
|
|
||||||
} currentUid:${currentUid} asyncHooksCurrentId:${asyncHooksCurrentId} triggerId:${triggerId} len:${
|
|
||||||
this._set.length
|
|
||||||
} active:${util.inspect(this.active)}`
|
|
||||||
)
|
|
||||||
}
|
|
||||||
return this.active[key]
|
|
||||||
}
|
|
||||||
|
|
||||||
Namespace.prototype.createContext = function createContext() {
|
|
||||||
// Prototype inherit existing context if created a new child context within existing context.
|
|
||||||
let context = Object.create(this.active ? this.active : Object.prototype)
|
|
||||||
context._ns_name = this.name
|
|
||||||
context.id = currentUid
|
|
||||||
|
|
||||||
if (DEBUG_CLS_HOOKED) {
|
|
||||||
const asyncHooksCurrentId = async_hooks.executionAsyncId()
|
|
||||||
const triggerId = async_hooks.triggerAsyncId()
|
|
||||||
const indentStr = " ".repeat(this._indent < 0 ? 0 : this._indent)
|
|
||||||
debug2(
|
|
||||||
`${indentStr}CONTEXT-CREATED Context: (${
|
|
||||||
this.name
|
|
||||||
}) currentUid:${currentUid} asyncHooksCurrentId:${asyncHooksCurrentId} triggerId:${triggerId} len:${
|
|
||||||
this._set.length
|
|
||||||
} context:${util.inspect(context, {
|
|
||||||
showHidden: true,
|
|
||||||
depth: 2,
|
|
||||||
colors: true,
|
|
||||||
})}`
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return context
|
|
||||||
}
|
|
||||||
|
|
||||||
Namespace.prototype.run = function run(fn) {
|
|
||||||
let context = this.createContext()
|
|
||||||
this.enter(context)
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (DEBUG_CLS_HOOKED) {
|
|
||||||
const triggerId = async_hooks.triggerAsyncId()
|
|
||||||
const asyncHooksCurrentId = async_hooks.executionAsyncId()
|
|
||||||
const indentStr = " ".repeat(this._indent < 0 ? 0 : this._indent)
|
|
||||||
debug2(
|
|
||||||
`${indentStr}CONTEXT-RUN BEGIN: (${
|
|
||||||
this.name
|
|
||||||
}) currentUid:${currentUid} triggerId:${triggerId} asyncHooksCurrentId:${asyncHooksCurrentId} len:${
|
|
||||||
this._set.length
|
|
||||||
} context:${util.inspect(context)}`
|
|
||||||
)
|
|
||||||
}
|
|
||||||
fn(context)
|
|
||||||
return context
|
|
||||||
} catch (exception) {
|
|
||||||
if (exception) {
|
|
||||||
exception[ERROR_SYMBOL] = context
|
|
||||||
}
|
|
||||||
throw exception
|
|
||||||
} finally {
|
|
||||||
if (DEBUG_CLS_HOOKED) {
|
|
||||||
const triggerId = async_hooks.triggerAsyncId()
|
|
||||||
const asyncHooksCurrentId = async_hooks.executionAsyncId()
|
|
||||||
const indentStr = " ".repeat(this._indent < 0 ? 0 : this._indent)
|
|
||||||
debug2(
|
|
||||||
`${indentStr}CONTEXT-RUN END: (${
|
|
||||||
this.name
|
|
||||||
}) currentUid:${currentUid} triggerId:${triggerId} asyncHooksCurrentId:${asyncHooksCurrentId} len:${
|
|
||||||
this._set.length
|
|
||||||
} ${util.inspect(context)}`
|
|
||||||
)
|
|
||||||
}
|
|
||||||
this.exit(context)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Namespace.prototype.runAndReturn = function runAndReturn(fn) {
|
|
||||||
let value
|
|
||||||
this.run(function (context) {
|
|
||||||
value = fn(context)
|
|
||||||
})
|
|
||||||
return value
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Uses global Promise and assumes Promise is cls friendly or wrapped already.
|
|
||||||
* @param {function} fn
|
|
||||||
* @returns {*}
|
|
||||||
*/
|
|
||||||
Namespace.prototype.runPromise = function runPromise(fn) {
|
|
||||||
let context = this.createContext()
|
|
||||||
this.enter(context)
|
|
||||||
|
|
||||||
let promise = fn(context)
|
|
||||||
if (!promise || !promise.then || !promise.catch) {
|
|
||||||
throw new Error("fn must return a promise.")
|
|
||||||
}
|
|
||||||
|
|
||||||
if (DEBUG_CLS_HOOKED) {
|
|
||||||
debug2(
|
|
||||||
"CONTEXT-runPromise BEFORE: (" +
|
|
||||||
this.name +
|
|
||||||
") currentUid:" +
|
|
||||||
currentUid +
|
|
||||||
" len:" +
|
|
||||||
this._set.length +
|
|
||||||
" " +
|
|
||||||
util.inspect(context)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return promise
|
|
||||||
.then(result => {
|
|
||||||
if (DEBUG_CLS_HOOKED) {
|
|
||||||
debug2(
|
|
||||||
"CONTEXT-runPromise AFTER then: (" +
|
|
||||||
this.name +
|
|
||||||
") currentUid:" +
|
|
||||||
currentUid +
|
|
||||||
" len:" +
|
|
||||||
this._set.length +
|
|
||||||
" " +
|
|
||||||
util.inspect(context)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
this.exit(context)
|
|
||||||
return result
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
err[ERROR_SYMBOL] = context
|
|
||||||
if (DEBUG_CLS_HOOKED) {
|
|
||||||
debug2(
|
|
||||||
"CONTEXT-runPromise AFTER catch: (" +
|
|
||||||
this.name +
|
|
||||||
") currentUid:" +
|
|
||||||
currentUid +
|
|
||||||
" len:" +
|
|
||||||
this._set.length +
|
|
||||||
" " +
|
|
||||||
util.inspect(context)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
this.exit(context)
|
|
||||||
throw err
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
Namespace.prototype.bind = function bindFactory(fn, context) {
|
|
||||||
if (!context) {
|
|
||||||
if (!this.active) {
|
|
||||||
context = this.createContext()
|
|
||||||
} else {
|
|
||||||
context = this.active
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let self = this
|
|
||||||
return function clsBind() {
|
|
||||||
self.enter(context)
|
|
||||||
try {
|
|
||||||
return fn.apply(this, arguments)
|
|
||||||
} catch (exception) {
|
|
||||||
if (exception) {
|
|
||||||
exception[ERROR_SYMBOL] = context
|
|
||||||
}
|
|
||||||
throw exception
|
|
||||||
} finally {
|
|
||||||
self.exit(context)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Namespace.prototype.enter = function enter(context) {
|
|
||||||
assert.ok(context, "context must be provided for entering")
|
|
||||||
if (DEBUG_CLS_HOOKED) {
|
|
||||||
const asyncHooksCurrentId = async_hooks.executionAsyncId()
|
|
||||||
const triggerId = async_hooks.triggerAsyncId()
|
|
||||||
const indentStr = " ".repeat(this._indent < 0 ? 0 : this._indent)
|
|
||||||
debug2(
|
|
||||||
`${indentStr}CONTEXT-ENTER: (${
|
|
||||||
this.name
|
|
||||||
}) currentUid:${currentUid} triggerId:${triggerId} asyncHooksCurrentId:${asyncHooksCurrentId} len:${
|
|
||||||
this._set.length
|
|
||||||
} ${util.inspect(context)}`
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
this._set.push(this.active)
|
|
||||||
this.active = context
|
|
||||||
}
|
|
||||||
|
|
||||||
Namespace.prototype.exit = function exit(context) {
|
|
||||||
assert.ok(context, "context must be provided for exiting")
|
|
||||||
if (DEBUG_CLS_HOOKED) {
|
|
||||||
const asyncHooksCurrentId = async_hooks.executionAsyncId()
|
|
||||||
const triggerId = async_hooks.triggerAsyncId()
|
|
||||||
const indentStr = " ".repeat(this._indent < 0 ? 0 : this._indent)
|
|
||||||
debug2(
|
|
||||||
`${indentStr}CONTEXT-EXIT: (${
|
|
||||||
this.name
|
|
||||||
}) currentUid:${currentUid} triggerId:${triggerId} asyncHooksCurrentId:${asyncHooksCurrentId} len:${
|
|
||||||
this._set.length
|
|
||||||
} ${util.inspect(context)}`
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fast path for most exits that are at the top of the stack
|
|
||||||
if (this.active === context) {
|
|
||||||
assert.ok(this._set.length, "can't remove top context")
|
|
||||||
this.active = this._set.pop()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fast search in the stack using lastIndexOf
|
|
||||||
let index = this._set.lastIndexOf(context)
|
|
||||||
|
|
||||||
if (index < 0) {
|
|
||||||
if (DEBUG_CLS_HOOKED) {
|
|
||||||
debug2(
|
|
||||||
"??ERROR?? context exiting but not entered - ignoring: " +
|
|
||||||
util.inspect(context)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
assert.ok(
|
|
||||||
index >= 0,
|
|
||||||
"context not currently entered; can't exit. \n" +
|
|
||||||
util.inspect(this) +
|
|
||||||
"\n" +
|
|
||||||
util.inspect(context)
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
assert.ok(index, "can't remove top context")
|
|
||||||
this._set.splice(index, 1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Namespace.prototype.bindEmitter = function bindEmitter(emitter) {
|
|
||||||
assert.ok(
|
|
||||||
emitter.on && emitter.addListener && emitter.emit,
|
|
||||||
"can only bind real EEs"
|
|
||||||
)
|
|
||||||
|
|
||||||
let namespace = this
|
|
||||||
let thisSymbol = "context@" + this.name
|
|
||||||
|
|
||||||
// Capture the context active at the time the emitter is bound.
|
|
||||||
function attach(listener) {
|
|
||||||
if (!listener) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (!listener[CONTEXTS_SYMBOL]) {
|
|
||||||
listener[CONTEXTS_SYMBOL] = Object.create(null)
|
|
||||||
}
|
|
||||||
|
|
||||||
listener[CONTEXTS_SYMBOL][thisSymbol] = {
|
|
||||||
namespace: namespace,
|
|
||||||
context: namespace.active,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// At emit time, bind the listener within the correct context.
|
|
||||||
function bind(unwrapped) {
|
|
||||||
if (!(unwrapped && unwrapped[CONTEXTS_SYMBOL])) {
|
|
||||||
return unwrapped
|
|
||||||
}
|
|
||||||
|
|
||||||
let wrapped = unwrapped
|
|
||||||
let unwrappedContexts = unwrapped[CONTEXTS_SYMBOL]
|
|
||||||
Object.keys(unwrappedContexts).forEach(function (name) {
|
|
||||||
let thunk = unwrappedContexts[name]
|
|
||||||
wrapped = thunk.namespace.bind(wrapped, thunk.context)
|
|
||||||
})
|
|
||||||
return wrapped
|
|
||||||
}
|
|
||||||
|
|
||||||
wrapEmitter(emitter, attach, bind)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If an error comes out of a namespace, it will have a context attached to it.
|
|
||||||
* This function knows how to find it.
|
|
||||||
*
|
|
||||||
* @param {Error} exception Possibly annotated error.
|
|
||||||
*/
|
|
||||||
Namespace.prototype.fromException = function fromException(exception) {
|
|
||||||
return exception[ERROR_SYMBOL]
|
|
||||||
}
|
|
||||||
|
|
||||||
function getNamespace(name) {
|
|
||||||
return process.namespaces[name]
|
|
||||||
}
|
|
||||||
|
|
||||||
function createNamespace(name) {
|
|
||||||
assert.ok(name, "namespace must be given a name.")
|
|
||||||
|
|
||||||
if (DEBUG_CLS_HOOKED) {
|
|
||||||
debug2(`NS-CREATING NAMESPACE (${name})`)
|
|
||||||
}
|
|
||||||
let namespace = new Namespace(name)
|
|
||||||
namespace.id = currentUid
|
|
||||||
|
|
||||||
const hook = async_hooks.createHook({
|
|
||||||
init(asyncId, type, triggerId, resource) {
|
|
||||||
currentUid = async_hooks.executionAsyncId()
|
|
||||||
|
|
||||||
//CHAIN Parent's Context onto child if none exists. This is needed to pass net-events.spec
|
|
||||||
// let initContext = namespace.active;
|
|
||||||
// if(!initContext && triggerId) {
|
|
||||||
// let parentContext = namespace._contexts.get(triggerId);
|
|
||||||
// if (parentContext) {
|
|
||||||
// namespace.active = parentContext;
|
|
||||||
// namespace._contexts.set(currentUid, parentContext);
|
|
||||||
// if (DEBUG_CLS_HOOKED) {
|
|
||||||
// const indentStr = ' '.repeat(namespace._indent < 0 ? 0 : namespace._indent);
|
|
||||||
// debug2(`${indentStr}INIT [${type}] (${name}) WITH PARENT CONTEXT asyncId:${asyncId} currentUid:${currentUid} triggerId:${triggerId} active:${util.inspect(namespace.active, true)} resource:${resource}`);
|
|
||||||
// }
|
|
||||||
// } else if (DEBUG_CLS_HOOKED) {
|
|
||||||
// const indentStr = ' '.repeat(namespace._indent < 0 ? 0 : namespace._indent);
|
|
||||||
// debug2(`${indentStr}INIT [${type}] (${name}) MISSING CONTEXT asyncId:${asyncId} currentUid:${currentUid} triggerId:${triggerId} active:${util.inspect(namespace.active, true)} resource:${resource}`);
|
|
||||||
// }
|
|
||||||
// }else {
|
|
||||||
// namespace._contexts.set(currentUid, namespace.active);
|
|
||||||
// if (DEBUG_CLS_HOOKED) {
|
|
||||||
// const indentStr = ' '.repeat(namespace._indent < 0 ? 0 : namespace._indent);
|
|
||||||
// debug2(`${indentStr}INIT [${type}] (${name}) asyncId:${asyncId} currentUid:${currentUid} triggerId:${triggerId} active:${util.inspect(namespace.active, true)} resource:${resource}`);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
if (namespace.active) {
|
|
||||||
namespace._contexts.set(asyncId, namespace.active)
|
|
||||||
|
|
||||||
if (DEBUG_CLS_HOOKED) {
|
|
||||||
const indentStr = " ".repeat(
|
|
||||||
namespace._indent < 0 ? 0 : namespace._indent
|
|
||||||
)
|
|
||||||
debug2(
|
|
||||||
`${indentStr}INIT [${type}] (${name}) asyncId:${asyncId} currentUid:${currentUid} triggerId:${triggerId} active:${util.inspect(
|
|
||||||
namespace.active,
|
|
||||||
{ showHidden: true, depth: 2, colors: true }
|
|
||||||
)} resource:${resource}`
|
|
||||||
)
|
|
||||||
}
|
|
||||||
} else if (currentUid === 0) {
|
|
||||||
// CurrentId will be 0 when triggered from C++. Promise events
|
|
||||||
// https://github.com/nodejs/node/blob/master/doc/api/async_hooks.md#triggerid
|
|
||||||
const triggerId = async_hooks.triggerAsyncId()
|
|
||||||
const triggerIdContext = namespace._contexts.get(triggerId)
|
|
||||||
if (triggerIdContext) {
|
|
||||||
namespace._contexts.set(asyncId, triggerIdContext)
|
|
||||||
if (DEBUG_CLS_HOOKED) {
|
|
||||||
const indentStr = " ".repeat(
|
|
||||||
namespace._indent < 0 ? 0 : namespace._indent
|
|
||||||
)
|
|
||||||
debug2(
|
|
||||||
`${indentStr}INIT USING CONTEXT FROM TRIGGERID [${type}] (${name}) asyncId:${asyncId} currentUid:${currentUid} triggerId:${triggerId} active:${util.inspect(
|
|
||||||
namespace.active,
|
|
||||||
{ showHidden: true, depth: 2, colors: true }
|
|
||||||
)} resource:${resource}`
|
|
||||||
)
|
|
||||||
}
|
|
||||||
} else if (DEBUG_CLS_HOOKED) {
|
|
||||||
const indentStr = " ".repeat(
|
|
||||||
namespace._indent < 0 ? 0 : namespace._indent
|
|
||||||
)
|
|
||||||
debug2(
|
|
||||||
`${indentStr}INIT MISSING CONTEXT [${type}] (${name}) asyncId:${asyncId} currentUid:${currentUid} triggerId:${triggerId} active:${util.inspect(
|
|
||||||
namespace.active,
|
|
||||||
{ showHidden: true, depth: 2, colors: true }
|
|
||||||
)} resource:${resource}`
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (DEBUG_CLS_HOOKED && type === "PROMISE") {
|
|
||||||
debug2(util.inspect(resource, { showHidden: true }))
|
|
||||||
const parentId = resource.parentId
|
|
||||||
const indentStr = " ".repeat(
|
|
||||||
namespace._indent < 0 ? 0 : namespace._indent
|
|
||||||
)
|
|
||||||
debug2(
|
|
||||||
`${indentStr}INIT RESOURCE-PROMISE [${type}] (${name}) parentId:${parentId} asyncId:${asyncId} currentUid:${currentUid} triggerId:${triggerId} active:${util.inspect(
|
|
||||||
namespace.active,
|
|
||||||
{ showHidden: true, depth: 2, colors: true }
|
|
||||||
)} resource:${resource}`
|
|
||||||
)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
before(asyncId) {
|
|
||||||
currentUid = async_hooks.executionAsyncId()
|
|
||||||
let context
|
|
||||||
|
|
||||||
/*
|
|
||||||
if(currentUid === 0){
|
|
||||||
// CurrentId will be 0 when triggered from C++. Promise events
|
|
||||||
// https://github.com/nodejs/node/blob/master/doc/api/async_hooks.md#triggerid
|
|
||||||
//const triggerId = async_hooks.triggerAsyncId();
|
|
||||||
context = namespace._contexts.get(asyncId); // || namespace._contexts.get(triggerId);
|
|
||||||
}else{
|
|
||||||
context = namespace._contexts.get(currentUid);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
//HACK to work with promises until they are fixed in node > 8.1.1
|
|
||||||
context =
|
|
||||||
namespace._contexts.get(asyncId) || namespace._contexts.get(currentUid)
|
|
||||||
|
|
||||||
if (context) {
|
|
||||||
if (DEBUG_CLS_HOOKED) {
|
|
||||||
const triggerId = async_hooks.triggerAsyncId()
|
|
||||||
const indentStr = " ".repeat(
|
|
||||||
namespace._indent < 0 ? 0 : namespace._indent
|
|
||||||
)
|
|
||||||
debug2(
|
|
||||||
`${indentStr}BEFORE (${name}) asyncId:${asyncId} currentUid:${currentUid} triggerId:${triggerId} active:${util.inspect(
|
|
||||||
namespace.active,
|
|
||||||
{ showHidden: true, depth: 2, colors: true }
|
|
||||||
)} context:${util.inspect(context)}`
|
|
||||||
)
|
|
||||||
namespace._indent += 2
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace.enter(context)
|
|
||||||
} else if (DEBUG_CLS_HOOKED) {
|
|
||||||
const triggerId = async_hooks.triggerAsyncId()
|
|
||||||
const indentStr = " ".repeat(
|
|
||||||
namespace._indent < 0 ? 0 : namespace._indent
|
|
||||||
)
|
|
||||||
debug2(
|
|
||||||
`${indentStr}BEFORE MISSING CONTEXT (${name}) asyncId:${asyncId} currentUid:${currentUid} triggerId:${triggerId} active:${util.inspect(
|
|
||||||
namespace.active,
|
|
||||||
{ showHidden: true, depth: 2, colors: true }
|
|
||||||
)} namespace._contexts:${util.inspect(namespace._contexts, {
|
|
||||||
showHidden: true,
|
|
||||||
depth: 2,
|
|
||||||
colors: true,
|
|
||||||
})}`
|
|
||||||
)
|
|
||||||
namespace._indent += 2
|
|
||||||
}
|
|
||||||
},
|
|
||||||
after(asyncId) {
|
|
||||||
currentUid = async_hooks.executionAsyncId()
|
|
||||||
let context // = namespace._contexts.get(currentUid);
|
|
||||||
/*
|
|
||||||
if(currentUid === 0){
|
|
||||||
// CurrentId will be 0 when triggered from C++. Promise events
|
|
||||||
// https://github.com/nodejs/node/blob/master/doc/api/async_hooks.md#triggerid
|
|
||||||
//const triggerId = async_hooks.triggerAsyncId();
|
|
||||||
context = namespace._contexts.get(asyncId); // || namespace._contexts.get(triggerId);
|
|
||||||
}else{
|
|
||||||
context = namespace._contexts.get(currentUid);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
//HACK to work with promises until they are fixed in node > 8.1.1
|
|
||||||
context =
|
|
||||||
namespace._contexts.get(asyncId) || namespace._contexts.get(currentUid)
|
|
||||||
|
|
||||||
if (context) {
|
|
||||||
if (DEBUG_CLS_HOOKED) {
|
|
||||||
const triggerId = async_hooks.triggerAsyncId()
|
|
||||||
namespace._indent -= 2
|
|
||||||
const indentStr = " ".repeat(
|
|
||||||
namespace._indent < 0 ? 0 : namespace._indent
|
|
||||||
)
|
|
||||||
debug2(
|
|
||||||
`${indentStr}AFTER (${name}) asyncId:${asyncId} currentUid:${currentUid} triggerId:${triggerId} active:${util.inspect(
|
|
||||||
namespace.active,
|
|
||||||
{ showHidden: true, depth: 2, colors: true }
|
|
||||||
)} context:${util.inspect(context)}`
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace.exit(context)
|
|
||||||
} else if (DEBUG_CLS_HOOKED) {
|
|
||||||
const triggerId = async_hooks.triggerAsyncId()
|
|
||||||
namespace._indent -= 2
|
|
||||||
const indentStr = " ".repeat(
|
|
||||||
namespace._indent < 0 ? 0 : namespace._indent
|
|
||||||
)
|
|
||||||
debug2(
|
|
||||||
`${indentStr}AFTER MISSING CONTEXT (${name}) asyncId:${asyncId} currentUid:${currentUid} triggerId:${triggerId} active:${util.inspect(
|
|
||||||
namespace.active,
|
|
||||||
{ showHidden: true, depth: 2, colors: true }
|
|
||||||
)} context:${util.inspect(context)}`
|
|
||||||
)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
destroy(asyncId) {
|
|
||||||
currentUid = async_hooks.executionAsyncId()
|
|
||||||
if (DEBUG_CLS_HOOKED) {
|
|
||||||
const triggerId = async_hooks.triggerAsyncId()
|
|
||||||
const indentStr = " ".repeat(
|
|
||||||
namespace._indent < 0 ? 0 : namespace._indent
|
|
||||||
)
|
|
||||||
debug2(
|
|
||||||
`${indentStr}DESTROY (${name}) currentUid:${currentUid} asyncId:${asyncId} triggerId:${triggerId} active:${util.inspect(
|
|
||||||
namespace.active,
|
|
||||||
{ showHidden: true, depth: 2, colors: true }
|
|
||||||
)} context:${util.inspect(namespace._contexts.get(currentUid))}`
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace._contexts.delete(asyncId)
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
hook.enable()
|
|
||||||
namespace._hook = hook
|
|
||||||
|
|
||||||
process.namespaces[name] = namespace
|
|
||||||
return namespace
|
|
||||||
}
|
|
||||||
|
|
||||||
function destroyNamespace(name) {
|
|
||||||
let namespace = getNamespace(name)
|
|
||||||
|
|
||||||
assert.ok(namespace, "can't delete nonexistent namespace! \"" + name + '"')
|
|
||||||
assert.ok(
|
|
||||||
namespace.id,
|
|
||||||
"don't assign to process.namespaces directly! " + util.inspect(namespace)
|
|
||||||
)
|
|
||||||
|
|
||||||
namespace._hook.disable()
|
|
||||||
namespace._contexts = null
|
|
||||||
process.namespaces[name] = null
|
|
||||||
}
|
|
||||||
|
|
||||||
function reset() {
|
|
||||||
// must unregister async listeners
|
|
||||||
if (process.namespaces) {
|
|
||||||
Object.keys(process.namespaces).forEach(function (name) {
|
|
||||||
destroyNamespace(name)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
process.namespaces = Object.create(null)
|
|
||||||
}
|
|
||||||
|
|
||||||
process.namespaces = process.namespaces || {}
|
|
||||||
|
|
||||||
//const fs = require('fs');
|
|
||||||
function debug2(...args) {
|
|
||||||
if (DEBUG_CLS_HOOKED) {
|
|
||||||
//fs.writeSync(1, `${util.format(...args)}\n`);
|
|
||||||
process._rawDebug(`${util.format(...args)}`)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*function getFunctionName(fn) {
|
|
||||||
if (!fn) {
|
|
||||||
return fn;
|
|
||||||
}
|
|
||||||
if (typeof fn === 'function') {
|
|
||||||
if (fn.name) {
|
|
||||||
return fn.name;
|
|
||||||
}
|
|
||||||
return (fn.toString().trim().match(/^function\s*([^\s(]+)/) || [])[1];
|
|
||||||
} else if (fn.constructor && fn.constructor.name) {
|
|
||||||
return fn.constructor.name;
|
|
||||||
}
|
|
||||||
}*/
|
|
|
@ -1,47 +0,0 @@
|
||||||
import cls from "../clshooked"
|
|
||||||
import { newid } from "../hashing"
|
|
||||||
|
|
||||||
const REQUEST_ID_KEY = "requestId"
|
|
||||||
const MAIN_CTX = cls.createNamespace("main")
|
|
||||||
|
|
||||||
function getContextStorage(namespace: any) {
|
|
||||||
if (namespace && namespace.active) {
|
|
||||||
let contextData = namespace.active
|
|
||||||
delete contextData.id
|
|
||||||
delete contextData._ns_name
|
|
||||||
return contextData
|
|
||||||
}
|
|
||||||
return {}
|
|
||||||
}
|
|
||||||
|
|
||||||
class FunctionContext {
|
|
||||||
static run(callback: any) {
|
|
||||||
return MAIN_CTX.runAndReturn(async () => {
|
|
||||||
const namespaceId = newid()
|
|
||||||
MAIN_CTX.set(REQUEST_ID_KEY, namespaceId)
|
|
||||||
const namespace = cls.createNamespace(namespaceId)
|
|
||||||
let response = await namespace.runAndReturn(callback)
|
|
||||||
cls.destroyNamespace(namespaceId)
|
|
||||||
return response
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
static setOnContext(key: string, value: any) {
|
|
||||||
const namespaceId = MAIN_CTX.get(REQUEST_ID_KEY)
|
|
||||||
const namespace = cls.getNamespace(namespaceId)
|
|
||||||
namespace.set(key, value)
|
|
||||||
}
|
|
||||||
|
|
||||||
static getFromContext(key: string) {
|
|
||||||
const namespaceId = MAIN_CTX.get(REQUEST_ID_KEY)
|
|
||||||
const namespace = cls.getNamespace(namespaceId)
|
|
||||||
const context = getContextStorage(namespace)
|
|
||||||
if (context) {
|
|
||||||
return context[key]
|
|
||||||
} else {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export = FunctionContext
|
|
|
@ -1,9 +1,5 @@
|
||||||
import { IdentityContext } from "@budibase/types"
|
import { IdentityContext } from "@budibase/types"
|
||||||
|
|
||||||
export enum ContextKey {
|
|
||||||
MAIN = "main",
|
|
||||||
}
|
|
||||||
|
|
||||||
export type ContextMap = {
|
export type ContextMap = {
|
||||||
tenantId?: string
|
tenantId?: string
|
||||||
appId?: string
|
appId?: string
|
||||||
|
|
|
@ -1,13 +1,16 @@
|
||||||
import env from "../environment"
|
import env from "../environment"
|
||||||
import { SEPARATOR, DocumentType } from "../db/constants"
|
import {
|
||||||
import cls from "./FunctionContext"
|
SEPARATOR,
|
||||||
import { baseGlobalDBName } from "../db/tenancy"
|
DocumentType,
|
||||||
|
getDevelopmentAppID,
|
||||||
|
getProdAppID,
|
||||||
|
baseGlobalDBName,
|
||||||
|
PouchLike,
|
||||||
|
} from "../db"
|
||||||
|
import { Context } from "./localStorage"
|
||||||
import { IdentityContext } from "@budibase/types"
|
import { IdentityContext } from "@budibase/types"
|
||||||
import { DEFAULT_TENANT_ID as _DEFAULT_TENANT_ID } from "../constants"
|
import { DEFAULT_TENANT_ID as _DEFAULT_TENANT_ID } from "../constants"
|
||||||
import { ContextMap, ContextKey } from "./constants"
|
import { ContextMap } from "./constants"
|
||||||
import { PouchLike } from "../db"
|
|
||||||
import { getDevelopmentAppID, getProdAppID } from "../db/conversions"
|
|
||||||
|
|
||||||
export const DEFAULT_TENANT_ID = _DEFAULT_TENANT_ID
|
export const DEFAULT_TENANT_ID = _DEFAULT_TENANT_ID
|
||||||
|
|
||||||
// some test cases call functions directly, need to
|
// some test cases call functions directly, need to
|
||||||
|
@ -19,7 +22,7 @@ export function isMultiTenant() {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isTenantIdSet() {
|
export function isTenantIdSet() {
|
||||||
const context = cls.getFromContext(ContextKey.MAIN) as ContextMap
|
const context = Context.get()
|
||||||
return !!context?.tenantId
|
return !!context?.tenantId
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,7 +56,7 @@ export function getTenantIDFromAppID(appId: string) {
|
||||||
function updateContext(updates: ContextMap) {
|
function updateContext(updates: ContextMap) {
|
||||||
let context: ContextMap
|
let context: ContextMap
|
||||||
try {
|
try {
|
||||||
context = cls.getFromContext(ContextKey.MAIN)
|
context = Context.get()
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// no context, start empty
|
// no context, start empty
|
||||||
context = {}
|
context = {}
|
||||||
|
@ -68,10 +71,7 @@ function updateContext(updates: ContextMap) {
|
||||||
async function newContext(updates: ContextMap, task: any) {
|
async function newContext(updates: ContextMap, task: any) {
|
||||||
// see if there already is a context setup
|
// see if there already is a context setup
|
||||||
let context: ContextMap = updateContext(updates)
|
let context: ContextMap = updateContext(updates)
|
||||||
return cls.run(async () => {
|
return Context.run(context, task)
|
||||||
cls.setOnContext(ContextKey.MAIN, context)
|
|
||||||
return await task()
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function doInContext(appId: string, task: any): Promise<any> {
|
export async function doInContext(appId: string, task: any): Promise<any> {
|
||||||
|
@ -132,7 +132,7 @@ export async function doInIdentityContext(
|
||||||
|
|
||||||
export function getIdentity(): IdentityContext | undefined {
|
export function getIdentity(): IdentityContext | undefined {
|
||||||
try {
|
try {
|
||||||
const context = cls.getFromContext(ContextKey.MAIN) as ContextMap
|
const context = Context.get()
|
||||||
return context?.identity
|
return context?.identity
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// do nothing - identity is not in context
|
// do nothing - identity is not in context
|
||||||
|
@ -143,7 +143,7 @@ export function getTenantId(): string {
|
||||||
if (!isMultiTenant()) {
|
if (!isMultiTenant()) {
|
||||||
return DEFAULT_TENANT_ID
|
return DEFAULT_TENANT_ID
|
||||||
}
|
}
|
||||||
const context = cls.getFromContext(ContextKey.MAIN) as ContextMap
|
const context = Context.get()
|
||||||
const tenantId = context?.tenantId
|
const tenantId = context?.tenantId
|
||||||
if (!tenantId) {
|
if (!tenantId) {
|
||||||
throw new Error("Tenant id not found")
|
throw new Error("Tenant id not found")
|
||||||
|
@ -152,7 +152,7 @@ export function getTenantId(): string {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getAppId(): string | undefined {
|
export function getAppId(): string | undefined {
|
||||||
const context = cls.getFromContext(ContextKey.MAIN) as ContextMap
|
const context = Context.get()
|
||||||
const foundId = context?.appId
|
const foundId = context?.appId
|
||||||
if (!foundId && env.isTest() && TEST_APP_ID) {
|
if (!foundId && env.isTest() && TEST_APP_ID) {
|
||||||
return TEST_APP_ID
|
return TEST_APP_ID
|
||||||
|
@ -165,7 +165,7 @@ export function updateTenantId(tenantId?: string) {
|
||||||
let context: ContextMap = updateContext({
|
let context: ContextMap = updateContext({
|
||||||
tenantId,
|
tenantId,
|
||||||
})
|
})
|
||||||
cls.setOnContext(ContextKey.MAIN, context)
|
Context.set(context)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function updateAppId(appId: string) {
|
export function updateAppId(appId: string) {
|
||||||
|
@ -173,7 +173,7 @@ export function updateAppId(appId: string) {
|
||||||
appId,
|
appId,
|
||||||
})
|
})
|
||||||
try {
|
try {
|
||||||
cls.setOnContext(ContextKey.MAIN, context)
|
Context.set(context)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (env.isTest()) {
|
if (env.isTest()) {
|
||||||
TEST_APP_ID = appId
|
TEST_APP_ID = appId
|
||||||
|
@ -184,7 +184,7 @@ export function updateAppId(appId: string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getGlobalDB(): PouchLike {
|
export function getGlobalDB(): PouchLike {
|
||||||
const context = cls.getFromContext(ContextKey.MAIN) as ContextMap
|
const context = Context.get()
|
||||||
return new PouchLike(baseGlobalDBName(context?.tenantId))
|
return new PouchLike(baseGlobalDBName(context?.tenantId))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
import { AsyncLocalStorage } from "async_hooks"
|
||||||
|
import { ContextMap } from "./constants"
|
||||||
|
|
||||||
|
export class Context {
|
||||||
|
static storage = new AsyncLocalStorage<ContextMap>()
|
||||||
|
|
||||||
|
static run(context: ContextMap, func: any) {
|
||||||
|
return Context.storage.run(context, () => func())
|
||||||
|
}
|
||||||
|
|
||||||
|
static get(): ContextMap {
|
||||||
|
return Context.storage.getStore() as ContextMap
|
||||||
|
}
|
||||||
|
|
||||||
|
static set(context: ContextMap) {
|
||||||
|
Context.storage.enterWith(context)
|
||||||
|
}
|
||||||
|
}
|
|
@ -53,7 +53,7 @@ export const getPouch = (opts: any = {}) => {
|
||||||
return PouchDB.defaults(POUCH_DB_DEFAULTS)
|
return PouchDB.defaults(POUCH_DB_DEFAULTS)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function init(opts?: PouchOptions) {
|
export function init(opts?: PouchOptions) {
|
||||||
Pouch = getPouch(opts)
|
Pouch = getPouch(opts)
|
||||||
initialised = true
|
initialised = true
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
import env from "../environment"
|
||||||
|
import { directCouchQuery, PouchLike } from "./couch"
|
||||||
|
import { CouchFindOptions } from "@budibase/types"
|
||||||
|
|
||||||
|
let initialised = false
|
||||||
|
const dbList = new Set()
|
||||||
|
|
||||||
|
const checkInitialised = () => {
|
||||||
|
if (!initialised) {
|
||||||
|
throw new Error("init has not been called")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getDB(dbName: string, opts?: any): PouchLike {
|
||||||
|
if (env.isTest()) {
|
||||||
|
dbList.add(dbName)
|
||||||
|
}
|
||||||
|
return new PouchLike(dbName, opts)
|
||||||
|
}
|
||||||
|
|
||||||
|
// we have to use a callback for this so that we can close
|
||||||
|
// the DB when we're done, without this manual requests would
|
||||||
|
// need to close the database when done with it to avoid memory leaks
|
||||||
|
export async function doWithDB(dbName: string, cb: any, opts = {}) {
|
||||||
|
const db = getDB(dbName, opts)
|
||||||
|
// need this to be async so that we can correctly close DB after all
|
||||||
|
// async operations have been completed
|
||||||
|
return await cb(db)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function allDbs() {
|
||||||
|
if (!env.isTest()) {
|
||||||
|
throw new Error("Cannot be used outside test environment.")
|
||||||
|
}
|
||||||
|
checkInitialised()
|
||||||
|
return [...dbList]
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function directCouchAllDbs(queryString?: string) {
|
||||||
|
let couchPath = "/_all_dbs"
|
||||||
|
if (queryString) {
|
||||||
|
couchPath += `?${queryString}`
|
||||||
|
}
|
||||||
|
return await directCouchQuery(couchPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function directCouchFind(dbName: string, opts: CouchFindOptions) {
|
||||||
|
const json = await directCouchQuery(`${dbName}/_find`, "POST", opts)
|
||||||
|
return { rows: json.docs, bookmark: json.bookmark }
|
||||||
|
}
|
|
@ -1,51 +1,7 @@
|
||||||
import env from "../environment"
|
export * from "./couch"
|
||||||
import { CouchFindOptions } from "@budibase/types"
|
export * from "./db"
|
||||||
import { directCouchQuery, PouchLike } from "./couch"
|
export * from "./utils"
|
||||||
export { init, PouchLike, getPouch, getPouchDB } from "./couch"
|
export * from "./views"
|
||||||
|
export * from "./constants"
|
||||||
let initialised = false
|
export * from "./conversions"
|
||||||
const dbList = new Set()
|
export * from "./tenancy"
|
||||||
|
|
||||||
const checkInitialised = () => {
|
|
||||||
if (!initialised) {
|
|
||||||
throw new Error("init has not been called")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getDB(dbName: string, opts?: any): PouchLike {
|
|
||||||
if (env.isTest()) {
|
|
||||||
dbList.add(dbName)
|
|
||||||
}
|
|
||||||
return new PouchLike(dbName, opts)
|
|
||||||
}
|
|
||||||
|
|
||||||
// we have to use a callback for this so that we can close
|
|
||||||
// the DB when we're done, without this manual requests would
|
|
||||||
// need to close the database when done with it to avoid memory leaks
|
|
||||||
export async function doWithDB(dbName: string, cb: any, opts = {}) {
|
|
||||||
const db = getDB(dbName, opts)
|
|
||||||
// need this to be async so that we can correctly close DB after all
|
|
||||||
// async operations have been completed
|
|
||||||
return await cb(db)
|
|
||||||
}
|
|
||||||
|
|
||||||
export function allDbs() {
|
|
||||||
if (!env.isTest()) {
|
|
||||||
throw new Error("Cannot be used outside test environment.")
|
|
||||||
}
|
|
||||||
checkInitialised()
|
|
||||||
return [...dbList]
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function directCouchAllDbs(queryString?: string) {
|
|
||||||
let couchPath = "/_all_dbs"
|
|
||||||
if (queryString) {
|
|
||||||
couchPath += `?${queryString}`
|
|
||||||
}
|
|
||||||
return await directCouchQuery(couchPath)
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function directCouchFind(dbName: string, opts: CouchFindOptions) {
|
|
||||||
const json = await directCouchQuery(`${dbName}/_find`, "POST", opts)
|
|
||||||
return { rows: json.docs, bookmark: json.bookmark }
|
|
||||||
}
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ import {
|
||||||
} from "./constants"
|
} from "./constants"
|
||||||
import { getTenantId, getGlobalDB } from "../context"
|
import { getTenantId, getGlobalDB } from "../context"
|
||||||
import { getGlobalDBName } from "./tenancy"
|
import { getGlobalDBName } from "./tenancy"
|
||||||
import { doWithDB, allDbs, directCouchAllDbs } from "./index"
|
import { doWithDB, allDbs, directCouchAllDbs } from "./db"
|
||||||
import { getAppMetadata } from "../cache/appMetadata"
|
import { getAppMetadata } from "../cache/appMetadata"
|
||||||
import { isDevApp, isDevAppID, getProdAppID } from "./conversions"
|
import { isDevApp, isDevAppID, getProdAppID } from "./conversions"
|
||||||
import { APP_PREFIX } from "./constants"
|
import { APP_PREFIX } from "./constants"
|
||||||
|
|
|
@ -24,7 +24,7 @@ import * as queue from "./queue"
|
||||||
import * as types from "./types"
|
import * as types from "./types"
|
||||||
|
|
||||||
// mimic the outer package exports
|
// mimic the outer package exports
|
||||||
import * as db from "./pkg/db"
|
import * as db from "./db"
|
||||||
import * as objectStore from "./pkg/objectStore"
|
import * as objectStore from "./pkg/objectStore"
|
||||||
import * as utils from "./pkg/utils"
|
import * as utils from "./pkg/utils"
|
||||||
import redis from "./pkg/redis"
|
import redis from "./pkg/redis"
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
// Mimic the outer package export for usage in index.ts
|
|
||||||
// The outer exports can't be used as they now reference dist directly
|
|
||||||
export * from "../db"
|
|
||||||
export * from "../db/utils"
|
|
||||||
export * from "../db/views"
|
|
||||||
export * from "../db/constants"
|
|
Loading…
Reference in New Issue