Skip to content

Commit

Permalink
refactor: tweaks
Browse files Browse the repository at this point in the history
  • Loading branch information
Kikobeats committed Nov 28, 2024
1 parent 99b9c0e commit 72d7a0e
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 80 deletions.
11 changes: 1 addition & 10 deletions packages/primitives/scripts/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,20 +82,12 @@ async function bundlePackage() {
},
/**
* Make sure that depdendencies between primitives are consumed
* externally instead of being bundled. Also polyfills stream/web
* with the web streams polyfill.
* externally instead of being bundled.
*/
{
name: 'import-path',
setup: (build) => {
build.onResolve({ filter: /.*$/ }, ({ kind, importer, path }) => {
if (path === 'stream/web') {
return {
path: './streams',
external: true,
}
}

const fullpath = resolve(importer, '..', path)
const isEntry = entryPoints.includes(`${fullpath}.js`)
if (kind !== 'entry-point' && isEntry && path.startsWith('.')) {
Expand Down Expand Up @@ -156,7 +148,6 @@ async function generateTextFiles() {
minify: true,
bundle: true,
platform: 'node',
external: ['./streams'],
})
const contents = minified.text
await fs.promises.writeFile(
Expand Down
133 changes: 63 additions & 70 deletions packages/primitives/src/primitives/load.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,57 +2,6 @@
/// <reference path="../injectSourceCode.d.ts" />

import Module from 'module'
import nodeCrypto from 'crypto'

/**
* @param {Object} params
* @param {unknown} params.context
* @param {Map<string, any>} [params.cache]
* @param {Set<string>} [params.references]
* @param {Record<string, any>} params.scopedContext
* @param {string} params.sourceCode
* @param {string} params.id
* @returns {any}
*/
function requireWithFakeGlobalScope(params) {
const getModuleCode = `(function(module,exports,require,globalThis,${Object.keys(
params.scopedContext,
).join(',')}) {${params.sourceCode}\n})`
const module = {
exports: {},
loaded: false,
id: params.id,
}

// @ts-ignore
const moduleRequire = (Module.createRequire || Module.createRequireFromPath)(
__filename,
)

/** @param {string} pathToRequire */
function throwingRequire(pathToRequire) {
if (pathToRequire.startsWith('./')) {
const moduleName = pathToRequire.replace(/^\.\//, '')
if (!params.cache || !params.cache.has(moduleName)) {
throw new Error(`Cannot find module '${moduleName}'`)
}
return params.cache.get(moduleName).exports
}
return moduleRequire(pathToRequire)
}

throwingRequire.resolve = moduleRequire.resolve.bind(moduleRequire)

eval(getModuleCode)(
module,
module.exports,
throwingRequire,
params.context,
...Object.values(params.scopedContext),
)

return module.exports
}

/**
* @returns {import('../../type-definitions/index')}
Expand All @@ -61,7 +10,7 @@ function requireWithFakeGlobalScope(params) {
export function load(scopedContext = {}) {
/** @type Record<string, any> */
const context = {}
assign(context, {
Object.assign(context, {
TextDecoder,
TextEncoder,
TextEncoderStream,
Expand All @@ -78,7 +27,7 @@ export function load(scopedContext = {}) {
sourceCode: injectSourceCode('./console.js'),
scopedContext,
})
assign(context, { console: consoleImpl.console })
Object.assign(context, { console: consoleImpl.console })

/** @type {import('../../type-definitions/timers')} */
const timersImpl = requireWithFakeGlobalScope({
Expand All @@ -87,7 +36,7 @@ export function load(scopedContext = {}) {
sourceCode: injectSourceCode('./timers.js'),
scopedContext,
})
assign(context, {
Object.assign(context, {
setTimeout: timersImpl.setTimeout,
setInterval: timersImpl.setInterval,
})
Expand All @@ -100,15 +49,15 @@ export function load(scopedContext = {}) {
scopedContext,
})

assign(context, {
Object.assign(context, {
Event,
EventTarget,
FetchEvent: eventsImpl.FetchEvent,
// @ts-expect-error we need to add this to the type definitions maybe
PromiseRejectionEvent: eventsImpl.PromiseRejectionEvent,
})

assign(context, require('./stream'))
Object.assign(context, require('./stream'))

/** @type {import('../../type-definitions/abort-controller')} */
const abortControllerImpl = requireWithFakeGlobalScope({
Expand All @@ -117,7 +66,7 @@ export function load(scopedContext = {}) {
sourceCode: injectSourceCode('./abort-controller.js'),
scopedContext: { ...scopedContext },
})
assign(context, {
Object.assign(context, {
AbortController: abortControllerImpl.AbortController,
AbortSignal: abortControllerImpl.AbortSignal,
DOMException: abortControllerImpl.DOMException,
Expand All @@ -130,21 +79,26 @@ export function load(scopedContext = {}) {
sourceCode: injectSourceCode('./url.js'),
scopedContext: { ...scopedContext },
})
assign(context, {
Object.assign(context, {
URL,
URLSearchParams,
URLPattern: urlImpl.URLPattern,
})
assign(context, { structuredClone })
assign(context, require('./fetch.js'))
assign(context, getCrypto(context, scopedContext))

Object.assign(context, { structuredClone })

Object.assign(context, require('./fetch.js'))

Object.assign(context, getCrypto(scopedContext))

// @ts-expect-error
return context
}

/**
* @returns {import('../../type-definitions/crypto')}
*/
function getCrypto(context, scopedContext) {
function getCrypto(scopedContext) {
/* it needs node19 to work */
if (typeof SubtleCrypto !== 'undefined' || scopedContext.SubtleCrypto) {
return {
Expand All @@ -155,7 +109,7 @@ function getCrypto(context, scopedContext) {
}
} else {
/** @type {any} */
const webcrypto = nodeCrypto.webcrypto
const webcrypto = require('crypto').webcrypto
return {
crypto: webcrypto,
Crypto: webcrypto.constructor,
Expand All @@ -166,12 +120,51 @@ function getCrypto(context, scopedContext) {
}

/**
* @template {Record<never, never>} T
* @template {object} U
* @param {T} context
* @param {U} additions
* @returns {asserts context is T & U}
* @param {Object} params
* @param {unknown} params.context
* @param {Map<string, any>} [params.cache]
* @param {Set<string>} [params.references]
* @param {Record<string, any>} params.scopedContext
* @param {string} params.sourceCode
* @param {string} params.id
* @returns {any}
*/
function assign(context, additions) {
Object.assign(context, additions)
function requireWithFakeGlobalScope(params) {
const getModuleCode = `(function(module,exports,require,globalThis,${Object.keys(
params.scopedContext,
).join(',')}) {${params.sourceCode}\n})`
const module = {
exports: {},
loaded: false,
id: params.id,
}

// @ts-ignore
const moduleRequire = (Module.createRequire || Module.createRequireFromPath)(
__filename,
)

/** @param {string} pathToRequire */
function throwingRequire(pathToRequire) {
if (pathToRequire.startsWith('./')) {
const moduleName = pathToRequire.replace(/^\.\//, '')
if (!params.cache || !params.cache.has(moduleName)) {
throw new Error(`Cannot find module '${moduleName}'`)
}
return params.cache.get(moduleName).exports
}
return moduleRequire(pathToRequire)
}

throwingRequire.resolve = moduleRequire.resolve.bind(moduleRequire)

eval(getModuleCode)(
module,
module.exports,
throwingRequire,
params.context,
...Object.values(params.scopedContext),
)

return module.exports
}

0 comments on commit 72d7a0e

Please sign in to comment.