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

dynohot

Package Overview
Dependencies
Maintainers
0
Versions
14
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

dynohot - npm Package Compare versions

Comparing version 1.1.5 to 1.2.0

4

dist/loader/loader.d.ts
export type { Hot } from "dynohot/hot";
export interface DynohotLoaderOptions {
ignore?: RegExp;
silent?: boolean;
}
//# sourceMappingURL=loader.d.ts.map

50

dist/loader/loader.js

@@ -8,8 +8,13 @@ import * as assert from "node:assert/strict";

import { transformModuleSource } from "./transform.js";
const self = new URL(import.meta.url);
const ignoreString = self.searchParams.get("ignore");
const ignorePattern = ignoreString === null ? /[/\\]node_modules[/\\]/ : new RegExp(ignoreString);
const root = String(new URL("..", self));
const runtimeURL = `${root}runtime/runtime.js?${String(self.searchParams)}`;
function extractImportAssertions(params) {
let ignorePattern;
let runtimeURL;
/** @internal */
export const initialize = ({ ignore: ignoreOption = /[/\\]node_modules[/\\]/, silent = false, } = {}) => {
ignorePattern = ignoreOption;
const root = String(new URL("..", new URL(import.meta.url)));
runtimeURL = `${root}runtime/runtime.js?${String(new URLSearchParams({
...silent ? { silent: "" } : {},
}))}`;
};
function extractImportAttributes(params) {
const entries = Array.from(Fn.transform(Fn.filter(params, entry => entry[0] === "with"), entry => new URLSearchParams(entry[1])));

@@ -19,7 +24,8 @@ entries.sort(Fn.mappedPrimitiveComparator(entry => entry[0]));

}
const makeAdapterModule = (url, importAssertions) => {
const deprecatedAssertSyntax = /^1[6-9]/.test(process.versions.node);
const makeAdapterModule = (url, importAttributes) => {
const encodedURL = JSON.stringify(url);
return (
// eslint-disable-next-line @stylistic/indent
`import * as namespace from ${encodedURL} assert ${JSON.stringify(importAssertions)};
`import * as namespace from ${encodedURL} ${deprecatedAssertSyntax ? "assert" : "with"} ${JSON.stringify(importAttributes)};
import { adapter } from "hot:runtime";

@@ -29,3 +35,3 @@ const module = adapter(${encodedURL}, namespace);

};
const makeJsonModule = (url, json, importAssertions) =>
const makeJsonModule = (url, json, importAttributes) =>
// eslint-disable-next-line @stylistic/indent

@@ -41,4 +47,4 @@ `import { acquire } from "hot:runtime"

}
module().load({ async: false, execute }, null, false, "json", ${JSON.stringify(importAssertions)}, []);\n`;
const makeReloadableModule = async (url, source, importAssertions) => {
module().load({ async: false, execute }, null, false, "json", ${JSON.stringify(importAttributes)}, []);\n`;
const makeReloadableModule = async (url, source, importAttributes) => {
const sourceMap = await async function () {

@@ -62,3 +68,5 @@ try {

// source as a post-transformation process.
return (`${transformModuleSource(url, importAssertions, source, sourceMap)}
return (
// eslint-disable-next-line @stylistic/indent
`${transformModuleSource(url, importAttributes, source, sourceMap)}
import { acquire } from "hot:runtime";

@@ -101,3 +109,3 @@ export default function module() { return acquire(${JSON.stringify(url)}); }\n`);

assert.ok(resolutionSpecifier !== null);
const importAssertions = extractImportAssertions(resolutionURL.searchParams);
const importAssertions = extractImportAttributes(resolutionURL.searchParams);
return maybeThen(function* () {

@@ -127,3 +135,3 @@ const result = yield nextResolve(resolutionSpecifier, {

assert.ok(parentModuleURL !== null);
const importAssertions = extractImportAssertions(resolutionURL.searchParams);
const importAssertions = extractImportAttributes(resolutionURL.searchParams);
return maybeThen(function* () {

@@ -183,3 +191,3 @@ const result = yield nextResolve(resolutionSpecifier, {

case "adapter": {
const importAssertions = extractImportAssertions(url.searchParams);
const importAssertions = extractImportAttributes(url.searchParams);
const moduleURL = url.searchParams.get("url");

@@ -207,10 +215,12 @@ assert.ok(moduleURL);

assert.ok(moduleURL);
const importAssertions = extractImportAssertions(url.searchParams);
const importAttributes = extractImportAttributes(url.searchParams);
const result = await nextLoad(moduleURL, {
...context,
importAssertions,
// TODO [marcel 2024-04-27]: remove after nodejs v18(?) is not supported
importAssertions: importAttributes,
importAttributes,
});
if (!ignorePattern.test(moduleURL)) {
if (result.format === "module") {
const source = await makeReloadableModule(moduleURL, asString(result.source), importAssertions);
const source = await makeReloadableModule(moduleURL, asString(result.source), importAttributes);
return { ...result, source };

@@ -222,3 +232,3 @@ }

format: "module",
source: makeJsonModule(moduleURL, asString(result.source), importAssertions),
source: makeJsonModule(moduleURL, asString(result.source), importAttributes),
};

@@ -230,3 +240,3 @@ }

format: "module",
source: makeAdapterModule(moduleURL, importAssertions),
source: makeAdapterModule(moduleURL, importAttributes),
};

@@ -233,0 +243,0 @@ }();

import { register } from "node:module";
// I can not believe they did this.
register("dynohot", {
register("dynohot/loader", {
parentURL: import.meta.url,
});
//# sourceMappingURL=register.js.map

@@ -1,2 +0,2 @@

export declare function transformModuleSource(filename: string, importAssertions: Record<string, string>, sourceText: string, sourceMap: unknown): string;
export declare function transformModuleSource(filename: string, importAttributes: Record<string, string>, sourceText: string, sourceMap: unknown): string;
//# sourceMappingURL=transform.d.ts.map

@@ -9,3 +9,4 @@ import * as assert from "node:assert/strict";

const extractName = (node) => t.isStringLiteral(node) ? node.value : node.name;
export function transformModuleSource(filename, importAssertions, sourceText, sourceMap) {
const deprecatedAssertSyntax = /^1[6-9]/.test(process.versions.node);
export function transformModuleSource(filename, importAttributes, sourceText, sourceMap) {
const file = function () {

@@ -67,3 +68,3 @@ try {

}), ", ")} ]`;
const loader = `module().load(${body}, ${importMeta}, ${state.usesDynamicImport}, "module", ${JSON.stringify(importAssertions)}, ${requestEntries});`;
const loader = `module().load(${body}, ${importMeta}, ${state.usesDynamicImport}, "module", ${JSON.stringify(importAttributes)}, ${requestEntries});`;
// Build final module source

@@ -79,4 +80,4 @@ return `${result.code}\n${sourceMapComment}\n${imports}\n${loader}\n`;

assert.ok(moduleRequest.source);
// Convert import assertions into `with` URL search parameters. That way the underlying
// loader can pass forward the assertions, but the runtime imports will be plain.
// Convert import attributes into `with` URL search parameters. That way the underlying
// loader can pass forward the attributes, but the runtime imports will be plain.
const attributes = moduleRequest.attributes ?? moduleRequest.assertions ?? [];

@@ -86,5 +87,5 @@ const specifier = moduleRequest.source.value;

["specifier", specifier],
...Fn.map(attributes, assertion => [
...Fn.map(attributes, attribute => [
"with",
String(new URLSearchParams([[extractName(assertion.key), extractName(assertion.value)]])),
String(new URLSearchParams([[extractName(attribute.key), extractName(attribute.value)]])),
]),

@@ -91,0 +92,0 @@ ]);

@@ -1,2 +0,1 @@

/// <reference types="node" resolution-mode="require"/>
import type { DynamicImport } from "./declaration.js";

@@ -3,0 +2,0 @@ import { EventEmitter } from "node:events";

@@ -157,3 +157,3 @@ import * as assert from "node:assert/strict";

assert.ok(instance !== undefined);
const { importAssertions } = instance.declaration;
const { importAttributes } = instance.declaration;
const params = new URLSearchParams([

@@ -163,3 +163,3 @@ ["url", this.url],

["format", instance.declaration.format],
...Fn.map(Object.entries(importAssertions), ([key, value]) => ["with", String(new URLSearchParams([[key, value]]))]),
...Fn.map(Object.entries(importAttributes), ([key, value]) => ["with", String(new URLSearchParams([[key, value]]))]),
]);

@@ -244,3 +244,3 @@ try {

// Invoked from transformed module source
load(body, meta, usesDynamicImport, format, importAssertions, loadedModules) {
load(body, meta, usesDynamicImport, format, importAttributes, loadedModules) {
if (evictModule) {

@@ -252,3 +252,3 @@ // Experimental module eviction

["version", String(this.version)],
...Object.entries(importAssertions).map(([key, value]) => ["with", String(new URLSearchParams([[key, value]]))]),
...Object.entries(importAttributes).map(([key, value]) => ["with", String(new URLSearchParams([[key, value]]))]),
]);

@@ -263,3 +263,3 @@ const backingModuleURL = `hot:module?${String(backingModuleParams)}`;

format,
importAssertions,
importAttributes,
usesDynamicImport,

@@ -266,0 +266,0 @@ loadedModules,

@@ -238,3 +238,3 @@ import * as assert from "node:assert/strict";

}
async dynamicImport(specifier, importAssertions) {
async dynamicImport(specifier, importAttributes) {
assert.ok(this.state.status === ModuleStatus.linked ||

@@ -247,5 +247,5 @@ this.state.status === ModuleStatus.evaluating ||

["specifier", specifier],
...Fn.map(Object.entries(importAssertions ?? {}), ([key, value]) => ["with", String(new URLSearchParams([[key, value]]))]),
...Fn.map(Object.entries(importAttributes ?? {}), ([key, value]) => ["with", String(new URLSearchParams([[key, value]]))]),
]);
const { default: acquire } = await this.controller.application.dynamicImport(`hot:import?${String(specifierParams)}`, importAssertions);
const { default: acquire } = await this.controller.application.dynamicImport(`hot:import?${String(specifierParams)}`, importAttributes);
const controller = acquire();

@@ -252,0 +252,0 @@ didDynamicImport(this, controller);

@@ -6,3 +6,3 @@ import { AdapterModuleController } from "./adapter.js";

/** @internal */
export const acquire = makeAcquire((specifier, assertions) => import(specifier, assertions), Object.fromEntries(params));
export const acquire = makeAcquire((specifier, attributes) => import(specifier, attributes), Object.fromEntries(params));
/** @internal */

@@ -9,0 +9,0 @@ export function adapter(url, namespace) {

@@ -28,3 +28,2 @@ import * as fs from "node:fs";

};
// @ts-expect-error - https://nodejs.org/api/fs.html#watcherunref
holder.watcher.unref();

@@ -31,0 +30,0 @@ this.watchers.set(directory, holder);

{
"name": "dynohot",
"type": "module",
"version": "1.1.5",
"version": "1.2.0",
"exports": {
".": "./dist/loader/loader.js",
"./?": "./dist/loader/loader.js",
"./?*": "./dist/loader/loader.js?*",
".": "./dist/loader/register.js",
"./loader": "./dist/loader/loader.js",
"./register": "./dist/loader/register.js",
"./register?": "./dist/loader/register.js",
"./register?*": "./dist/loader/register.js?*",
"./import-meta": {

@@ -26,18 +23,18 @@ "types": "./import-meta.d.ts"

"dependencies": {
"@babel/core": "^7.24.4",
"@babel/generator": "^7.23.0",
"@babel/traverse": "^7.23.2",
"@babel/core": "^7.24.7",
"@babel/generator": "^7.24.7",
"@babel/traverse": "^7.24.7",
"convert-source-map": "^2.0.0"
},
"devDependencies": {
"@babel/preset-env": "^7.23.2",
"@babel/preset-typescript": "^7.23.2",
"@babel/preset-env": "^7.24.7",
"@babel/preset-typescript": "^7.24.7",
"@braidai/eslintrc": "^1.0.0",
"@jest/globals": "^29.7.0",
"@jest/types": "^29.6.3",
"@types/babel__core": "^7.20.3",
"@types/babel__generator": "^7.6.6",
"@types/babel__traverse": "^7.20.3",
"@types/babel__core": "^7.20.5",
"@types/babel__generator": "^7.6.8",
"@types/babel__traverse": "^7.20.6",
"@types/convert-source-map": "^2.0.2",
"@types/node": "^20.8.9",
"@types/node": "^20.14.9",
"babel-jest": "^29.7.0",

@@ -47,3 +44,3 @@ "babel-plugin-transform-import-meta": "^2.2.1",

"jest": "^29.7.0",
"typescript": "^5.2.2"
"typescript": "^5.5.2"
},

@@ -50,0 +47,0 @@ "repository": {

@@ -14,5 +14,5 @@ [![npm version](https://badgen.now.sh/npm/v/dynohot)](https://www.npmjs.com/package/dynohot)

challenging to get them to run server-side apps. With the experimental nodejs loader API you can get
HMR running with a simple `--loader dynohot` [or `--import dynohot/register`] flag. You should
probably also add `--enable-source-maps` because dynohot applies a [transformation](#transformation)
to your source code.
HMR running with a simple `--import dynohot` flag. You should probably also add
`--enable-source-maps` because dynohot applies a [transformation](#transformation) to your source
code.

@@ -192,3 +192,3 @@ Note that your project *must* be using proper [JavaScript

```
node --import @loaderkit/ts/register --import dynohot/register ./main.ts
node --import @loaderkit/ts/register --import dynohot ./main.ts
```

@@ -294,10 +294,25 @@

You can pass options to dynohot using `--import dynohot/register?option=value` or `--loader dynohot/?option=value`.
You can pass options to dynohot by creating a registration runtime JavaScript file and importing it
instead of `--import dynohot`. For example:
* `ignore` - Pass `?ignore=regexpPattern` to explicitly ignore certain file paths. By default this is
`ignore=[/\]node_modules[/\]`.
* `silent` - Pass `?silent` to prevent logging messages to stderr console. You might want this if
you're using something like Winston or Pino. Be sure to use `import.meta.on("message", ...)` to
raise informative dynohot messages to the developer's attention.
`loaders.js`:
```js
import { register } from "node:module";
register("dynohot/loader", {
parentURL: import.meta.url,
data: {
silent: true,
},
});
```
* `ignore` - `RegExp` used to filter out modules which should not take place in hot reloading. The
string applied to the regular expression will be a fully-resolved file URL. The default value of
this parameter is `/[/\\]node_modules[/\\]/`.
* `silent` - `boolean` which will prevent `dynohot` from outputting diagnostic messages to stderr.
You might want this if you're using something like Winston or Pino. Be sure to use
`import.meta.on("message", ...)` to raise informative dynohot messages to the developer's
attention.
TRANSFORMATION

@@ -345,3 +360,3 @@ --------------

"module",
// import assertions `import .. with { type: "json" }`
// import attributes `import .. with { type: "json" }`
{},

@@ -348,0 +363,0 @@ // imports

@@ -120,3 +120,3 @@ import type { ReloadableModuleInstance } from "./instance.js";

if (acceptedModules.every(module => module != null)) {
return acceptedModules as ReloadableModuleController[];
return acceptedModules;
} else {

@@ -180,3 +180,3 @@ if (hot !== null) {

accepts,
modules: acceptedModules as ReloadableModuleController[],
modules: acceptedModules,
};

@@ -183,0 +183,0 @@ }

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc