Skip to content

Instantly share code, notes, and snippets.

@kumavis
Last active November 18, 2019 13:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kumavis/97d0e9f7d7506c9cda6734ea2a7ed97e to your computer and use it in GitHub Desktop.
Save kumavis/97d0e9f7d7506c9cda6734ea2a7ed97e to your computer and use it in GitHub Desktop.
simple membrane module system
const { Membrane } = require('es-membrane')
const { defineModule, getRawModule } = createModuleSystem()
//
// define modules
//
// module X
defineModule('x', (require) => {
const ref = {}
return {
get () { return ref },
check (target) { return target === ref },
}
})
// module Y
defineModule('y', (require) => {
const x = require('x')
return {
get () { return x.get() },
}
})
// module Z
defineModule('z', (require) => {
const x = require('x')
const y = require('y')
return {
test () { return x.check(y.get()) },
}
})
//
// test membrane interaction
//
const x = getRawModule('x')
const y = getRawModule('y')
const z = getRawModule('z')
// check ref equality via raw modules
console.log('raw module ref check:', x.get() === y.get()) //=> false
// check ref equality via membrane interaction
console.log('membrane ref check:', z.test()) //=> true
//
// module system infrastructure
//
function createModuleSystem () {
const { createView } = createMembrane()
const moduleRegistry = new Map()
return { defineModule, getRawModule }
function getRawModule (id) {
return moduleRegistry.get(id)
}
function defineModule (id, initFn) {
const requireFn = createRequireFnFor(id)
const moduleExports = initFn(requireFn)
moduleRegistry.set(id, moduleExports)
}
function createRequireFnFor (destinationId) {
return function require (originId) {
const moduleExports = moduleRegistry.get(originId)
const viewOfModuleExports = createView(moduleExports, originId, destinationId)
return viewOfModuleExports
}
}
}
function createMembrane () {
const membrane = new Membrane({})
const handlers = new Map()
return { createView }
function createHandler (id) {
handlers.set(id, membrane.getHandlerByName(id, { mustCreate: true }))
}
function createView (obj, originId, destinationId) {
// add handler for space if missing
if (!handlers.has(originId)) createHandler(originId)
if (!handlers.has(destinationId)) createHandler(destinationId)
// perform wrap
return membrane.convertArgumentToProxy(
handlers.get(originId),
handlers.get(destinationId),
obj
)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment