Socket
Socket
Sign inDemoInstall

backpage

Package Overview
Dependencies
Maintainers
1
Versions
37
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

backpage - npm Package Compare versions

Comparing version 0.0.1-7 to 0.0.1-8

bld/backpage/tunnels/frontpage-tunnel.d.ts

3

bld/backpage/@paths.d.ts
export declare const PROJECT_DIR: string;
export declare const RES_DIR: string;
export declare const BLD_DIR: string;
export declare const NODE_MODULES_DIR: string;
export declare const FRONTPAGE_RES_DIR: string;
export declare const FRONTPAGE_BLD_DIR: string;
export declare const FRONTPAGE_INDEX_PATH: string;
export declare const FRONTPAGE_MAIN_PATH: string;
export declare const FRONTPAGE_BUNDLED_PATH: string;

@@ -7,6 +7,8 @@ import { dirname, join } from 'path';

export const BLD_DIR = join(PROJECT_DIR, 'bld');
export const NODE_MODULES_DIR = join(PROJECT_DIR, 'node_modules');
// frontpage
export const FRONTPAGE_RES_DIR = join(RES_DIR, 'frontpage');
export const FRONTPAGE_BLD_DIR = join(BLD_DIR, 'frontpage');
export const FRONTPAGE_INDEX_PATH = join(FRONTPAGE_RES_DIR, 'index.html');
export const FRONTPAGE_MAIN_PATH = join(FRONTPAGE_BLD_DIR, 'main.js');
export const FRONTPAGE_BUNDLED_PATH = join(FRONTPAGE_BLD_DIR, 'bundled.js');
//# sourceMappingURL=@paths.js.map
import type { ReactNode } from 'react';
import type { SelfHostedTunnelOptions } from './tunnels/index.js';
export type BackPageOptions = SelfHostedTunnelOptions & {
import type { FrontPageTunnelOptions } from './tunnels/index.js';
export type BackPageOptions = FrontPageTunnelOptions & {
title?: string;

@@ -8,3 +8,3 @@ };

private tunnel;
private container;
private content;
private root;

@@ -11,0 +11,0 @@ private mutationObserver;

@@ -5,3 +5,3 @@ import React from 'react';

import { BackPageContext } from './components/index.js';
import { SelfHostedTunnel } from './tunnels/index.js';
import { FrontPageTunnel } from './tunnels/index.js';
export class BackPage {

@@ -15,3 +15,3 @@ constructor({ title, ...options } = {}) {

});
Object.defineProperty(this, "container", {
Object.defineProperty(this, "content", {
enumerable: true,

@@ -26,3 +26,3 @@ configurable: true,

writable: true,
value: createRoot(this.container)
value: createRoot(this.content)
});

@@ -35,3 +35,3 @@ Object.defineProperty(this, "mutationObserver", {

});
this.tunnel = new SelfHostedTunnel(options);
this.tunnel = new FrontPageTunnel(options);
if (title !== undefined) {

@@ -41,3 +41,3 @@ this.tunnel.update({ title });

this.mutationObserver = new window.MutationObserver(() => this.updateHTML());
this.mutationObserver.observe(this.container, {
this.mutationObserver.observe(this.content, {
attributes: true,

@@ -72,6 +72,7 @@ childList: true,

updateHTML() {
const html = this.container.innerHTML;
this.tunnel.update({ html });
this.tunnel.update({
content: this.content.cloneNode(true),
});
}
}
//# sourceMappingURL=backpage.js.map

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

import { randomBytes } from 'crypto';
import AnsiToHTML from 'ansi-to-html';

@@ -5,5 +6,11 @@ import patchConsole from 'patch-console';

const LIMIT_DEFAULT = 100;
let consolePatched = false;
export function Console({ limit = LIMIT_DEFAULT, colors, ...attrs }) {
const [idPrefix] = useState(() => `console-${randomBytes(2).toString('hex')}:`);
const [recentLines, setRecentLines] = useState([]);
useEffect(() => {
if (consolePatched) {
throw new Error('Console already patched, are you using multiple <Console /> component?');
}
consolePatched = true;
const ansiToHTML = new AnsiToHTML(

@@ -14,3 +21,3 @@ // AnsiToHTML seems to have problem with an undefined `colors` option.

const recentLines = [];
return patchConsole((type, data) => {
const restore = patchConsole((type, data) => {
process[type].write(data);

@@ -40,5 +47,9 @@ const lastMatchingLine = recentLines.findLast(line => line.type === type);

});
return () => {
consolePatched = false;
restore();
};
}, [colors, limit]);
return (React.createElement("pre", { ...attrs }, recentLines.map(({ key, type, html }) => (React.createElement("div", { key: key, className: type, dangerouslySetInnerHTML: { __html: html } })))));
return (React.createElement("pre", { ...attrs }, recentLines.map(({ key, type, html }) => (React.createElement("div", { key: key, id: `${idPrefix}${key}`, className: type, dangerouslySetInnerHTML: { __html: html } })))));
}
//# sourceMappingURL=console.js.map

@@ -17,3 +17,3 @@ import type { BackFrontMessage } from '../shared/index.js';

title?: string;
html?: string;
content?: HTMLDivElement;
};

@@ -20,0 +20,0 @@ export declare abstract class TunnelClient {

@@ -0,1 +1,7 @@

import DiffMatchPatch from 'diff-match-patch';
import { MultikeyMap } from 'multikey-map';
import { window } from './@jsdom.js';
const INITIAL_CONTENT = window.document.createElement('div');
INITIAL_CONTENT.innerHTML = '<div>BackPage</div>';
const dmp = new DiffMatchPatch();
export class Tunnel {

@@ -15,3 +21,3 @@ constructor() {

title: 'BackPage',
html: '<div>BackPage</div>',
content: INITIAL_CONTENT,
}

@@ -43,8 +49,14 @@ });

this.pendingUpdate = undefined;
const { title, html } = pendingUpdate;
const { title, content } = pendingUpdate;
if (title !== undefined && title !== snapshot.title) {
snapshot = { ...snapshot, title };
}
if (html !== undefined && html !== snapshot.html) {
snapshot = { ...snapshot, html };
if (content !== undefined) {
const patches = cachedDOMPatch(snapshot.content, content);
if (patches.length > 0) {
snapshot = {
...snapshot,
content,
};
}
}

@@ -60,3 +72,6 @@ if (snapshot === this.snapshot) {

addClient(client) {
const clientState = { idle: true };
const clientState = {
idle: true,
content: undefined,
};
this.clientStateMap.set(client, clientState);

@@ -72,5 +87,13 @@ this.sendUpdateToClient(client, clientState);

}
const { snapshot } = this;
const message = {
type: 'update',
title: snapshot.title,
content: clientState.content === undefined
? snapshot.content.innerHTML
: cachedDOMPatch(clientState.content, snapshot.content),
};
clientState.idle = false;
const { snapshot } = this;
void client.send({ type: 'update', ...snapshot }).then(() => {
clientState.content = snapshot.content;
void client.send(message).then(() => {
clientState.idle = true;

@@ -83,4 +106,14 @@ if (snapshot !== this.snapshot) {

}
const cachedDOMPatchesMap = new MultikeyMap();
function cachedDOMPatch(elementA, elementB) {
const cachedDiffs = cachedDOMPatchesMap.get([elementA, elementB]);
if (cachedDiffs) {
return cachedDiffs;
}
const patches = dmp.patch_make(elementA.innerHTML, elementB.innerHTML);
cachedDOMPatchesMap.set([elementA, elementB], patches);
return patches;
}
export class TunnelClient {
}
//# sourceMappingURL=tunnel.js.map

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

export * from './self-hosted-tunnel.js';
export * from './frontpage-tunnel.js';

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

export * from './self-hosted-tunnel.js';
export * from './frontpage-tunnel.js';
//# sourceMappingURL=index.js.map

@@ -0,4 +1,8 @@

import DiffMatchPatch from 'diff-match-patch';
import morphdom from 'morphdom';
// Using string replace also handles the case of HTTPS.
const WS_URL = new URL('/', location.href).href.replace(/^http/, 'ws');
const RECONNECT_INTERVAL = 1000;
const dmp = new DiffMatchPatch();
let html;
connect();

@@ -13,3 +17,15 @@ function connect() {

document.title = message.title;
document.body.innerHTML = message.html;
if (typeof message.content === 'string') {
html = message.content;
document.body.innerHTML = html;
}
else if (html !== undefined) {
[html] = dmp.patch_apply(message.content, html);
const body = document.createElement('body');
body.innerHTML = html;
morphdom(document.body, body);
}
else {
document.body.innerHTML = 'An error occurred.';
}
break;

@@ -26,3 +42,2 @@ }

}
export {};
//# sourceMappingURL=main.js.map

@@ -0,5 +1,6 @@

import type { DiffMatchPatches } from './diff-match-patch.js';
export type BackFrontMessage = {
type: 'update';
title: string;
html: string;
content: string | DiffMatchPatches;
};
export * from './back-front-message.js';
export * from './diff-match-patch.js';
export * from './back-front-message.js';
export * from './diff-match-patch.js';
//# sourceMappingURL=index.js.map
{
"name": "backpage",
"version": "0.0.1-7",
"version": "0.0.1-8",
"repository": "https://github.com/vilicvane/backpage.git",

@@ -20,3 +20,4 @@ "license": "MIT",

"3": "pnpm install && pnpm dedupe && pnpm install",
"build": "rimraf ./bld && tsc --build",
"build": "rimraf ./bld && tsc --build && pnpm build:rollup",
"build:rollup": "rollup --config ./rollup.config.js",
"lint": "eslint --no-error-on-unmatched-pattern --report-unused-disable-directives . && run-in-every eslint-project --parallel --echo -- eslint --no-error-on-unmatched-pattern --report-unused-disable-directives .",

@@ -27,2 +28,5 @@ "lint-prettier": "prettier --check .",

"dependencies": {
"@rollup/plugin-commonjs": "^25.0.7",
"@rollup/plugin-node-resolve": "^15.2.3",
"@types/diff-match-patch": "^1.0.36",
"@types/express": "^4.17.21",

@@ -35,7 +39,11 @@ "@types/express-ws": "^3.0.4",

"ansi-to-html": "^0.7.2",
"diff-match-patch": "^1.0.5",
"express": "^4.18.2",
"express-ws": "^5.0.2",
"jsdom": "^23.2.0",
"morphdom": "^2.7.1",
"multikey-map": "^0.2.1",
"patch-console": "^2.0.0",
"react-dom": "^18.2.0",
"rollup": "^4.9.5",
"tslib": "^2.6.2",

@@ -42,0 +50,0 @@ "ws": "^8.16.0"

@@ -99,6 +99,4 @@ [![NPM version](https://img.shields.io/npm/v/backpage?color=%23cb3837&style=flat-square)](https://www.npmjs.com/package/backpage)

> Console outputs are streamed as part of the HTML in a non-incremental way, so it is not recommended to use `<Console />` with a large `limit` number.
## License
MIT License.

@@ -11,2 +11,6 @@ import {dirname, join} from 'path';

export const NODE_MODULES_DIR = join(PROJECT_DIR, 'node_modules');
// frontpage
export const FRONTPAGE_RES_DIR = join(RES_DIR, 'frontpage');

@@ -18,2 +22,2 @@

export const FRONTPAGE_MAIN_PATH = join(FRONTPAGE_BLD_DIR, 'main.js');
export const FRONTPAGE_BUNDLED_PATH = join(FRONTPAGE_BLD_DIR, 'bundled.js');

@@ -1,3 +0,14 @@

import type {BackFrontMessage} from '../shared/index.js';
import DiffMatchPatch from 'diff-match-patch';
import {MultikeyMap} from 'multikey-map';
import type {BackFrontMessage, DiffMatchPatches} from '../shared/index.js';
import {window} from './@jsdom.js';
const INITIAL_CONTENT = window.document.createElement('div');
INITIAL_CONTENT.innerHTML = '<div>BackPage</div>';
const dmp = new DiffMatchPatch();
export abstract class Tunnel {

@@ -8,3 +19,3 @@ private clientStateMap = new Map<TunnelClient, ClientState>();

title: 'BackPage',
html: '<div>BackPage</div>',
content: INITIAL_CONTENT,
};

@@ -33,3 +44,3 @@

const {title, html} = pendingUpdate;
const {title, content} = pendingUpdate;

@@ -40,4 +51,11 @@ if (title !== undefined && title !== snapshot.title) {

if (html !== undefined && html !== snapshot.html) {
snapshot = {...snapshot, html};
if (content !== undefined) {
const patches = cachedDOMPatch(snapshot.content, content);
if (patches.length > 0) {
snapshot = {
...snapshot,
content,
};
}
}

@@ -61,3 +79,6 @@

protected addClient(client: TunnelClient): void {
const clientState: ClientState = {idle: true};
const clientState: ClientState = {
idle: true,
content: undefined,
};

@@ -80,8 +101,17 @@ this.clientStateMap.set(client, clientState);

}
const {snapshot} = this;
const message: BackFrontMessage = {
type: 'update',
title: snapshot.title,
content:
clientState.content === undefined
? snapshot.content.innerHTML
: cachedDOMPatch(clientState.content, snapshot.content),
};
clientState.idle = false;
clientState.content = snapshot.content;
const {snapshot} = this;
void client.send({type: 'update', ...snapshot}).then(() => {
void client.send(message).then(() => {
clientState.idle = true;

@@ -98,3 +128,3 @@

title?: string;
html?: string;
content?: HTMLDivElement;
};

@@ -104,3 +134,3 @@

title: string;
html: string;
content: HTMLDivElement;
};

@@ -110,6 +140,29 @@

idle: boolean;
content: HTMLDivElement | undefined;
};
const cachedDOMPatchesMap = new MultikeyMap<
[HTMLElement, HTMLElement],
DiffMatchPatches
>();
function cachedDOMPatch(
elementA: HTMLElement,
elementB: HTMLElement,
): DiffMatchPatches {
const cachedDiffs = cachedDOMPatchesMap.get([elementA, elementB]);
if (cachedDiffs) {
return cachedDiffs;
}
const patches = dmp.patch_make(elementA.innerHTML, elementB.innerHTML);
cachedDOMPatchesMap.set([elementA, elementB], patches);
return patches;
}
export abstract class TunnelClient {
abstract send(message: BackFrontMessage): Promise<void>;
}

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

export * from './self-hosted-tunnel.js';
export * from './frontpage-tunnel.js';

@@ -0,1 +1,4 @@

import DiffMatchPatch from 'diff-match-patch';
import morphdom from 'morphdom';
import type {BackFrontMessage} from '../shared/index.js';

@@ -8,2 +11,6 @@

const dmp = new DiffMatchPatch();
let html: string | undefined;
connect();

@@ -21,3 +28,19 @@

document.title = message.title;
document.body.innerHTML = message.html;
if (typeof message.content === 'string') {
html = message.content;
document.body.innerHTML = html;
} else if (html !== undefined) {
[html] = dmp.patch_apply(message.content, html);
const body = document.createElement('body');
body.innerHTML = html;
morphdom(document.body, body);
} else {
document.body.innerHTML = 'An error occurred.';
}
break;

@@ -24,0 +47,0 @@ }

@@ -0,5 +1,7 @@

import type {DiffMatchPatches} from './diff-match-patch.js';
export type BackFrontMessage = {
type: 'update';
title: string;
html: string;
content: string | DiffMatchPatches;
};
export * from './back-front-message.js';
export * from './diff-match-patch.js';

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

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

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

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