Socket
Socket
Sign inDemoInstall

react-streaming

Package Overview
Dependencies
8
Maintainers
1
Versions
69
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.3.18 to 0.3.19-commit-20b3bc7

dist/cjs/server/index.node.d.ts

5

dist/cjs/server/renderToStream.d.ts
export { renderToStream };
export { disable };
export { renderToNodeStream_set };
import React from 'react';
import type { renderToPipeableStream as RenderToPipeableStream, renderToReadableStream as RenderToReadableStream } from 'react-dom/server';
import { Pipe } from './renderToStream/createPipeWrapper';
import type { Pipe } from './renderToStream/createPipeWrapper';
import { SeoStrategy } from './renderToStream/resolveSeoStrategy';
import type { renderToNodeStream as RenderToNodeStream } from './renderToStream/renderToNodeStream';
declare type Options = {

@@ -29,1 +31,2 @@ webStream?: boolean;

declare function renderToStream(element: React.ReactNode, options?: Options): Promise<Result>;
declare function renderToNodeStream_set(renderToNodeStream: typeof RenderToNodeStream): void;

160

dist/cjs/server/renderToStream.js

@@ -29,3 +29,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.disable = exports.renderToStream = void 0;
exports.renderToNodeStream_set = exports.disable = exports.renderToStream = void 0;
const react_1 = __importDefault(require("react"));

@@ -35,9 +35,10 @@ const server_1 = __importStar(require("react-dom/server"));

const useStream_1 = require("./useStream");
const createPipeWrapper_1 = require("./renderToStream/createPipeWrapper");
const createReadableWrapper_1 = require("./renderToStream/createReadableWrapper");
const resolveSeoStrategy_1 = require("./renderToStream/resolveSeoStrategy");
const utils_1 = require("./utils");
const loadNodeStreamModule_1 = require("./renderToStream/loadNodeStreamModule");
const import_1 = __importDefault(require("@brillout/import"));
const debug = (0, utils_1.createDebugger)('react-streaming:flow');
const renderToWebStream_1 = require("./renderToStream/renderToWebStream");
const misc_1 = require("./renderToStream/misc");
const globalObject = (0, utils_1.getGlobalObject)('renderToStream.ts', {
renderToNodeStream: null
});
assertReact();

@@ -66,10 +67,10 @@ const globalConfig = (globalThis.__react_streaming = globalThis

const webStream = (_b = options.webStream) !== null && _b !== void 0 ? _b : !(await (0, loadNodeStreamModule_1.nodeStreamModuleIsAvailable)());
debug(`disable === ${disable} && webStream === ${webStream}`);
(0, misc_1.debugFlow)(`disable === ${disable} && webStream === ${webStream}`);
let result;
const resultPartial = { disabled: disable };
if (!webStream) {
result = Object.assign(Object.assign({}, resultPartial), (await renderToNodeStream(element, disable, options)));
result = Object.assign(Object.assign({}, resultPartial), (await globalObject.renderToNodeStream(element, disable, options)));
}
else {
result = Object.assign(Object.assign({}, resultPartial), (await renderToWebStream(element, disable, options)));
result = Object.assign(Object.assign({}, resultPartial), (await (0, renderToWebStream_1.renderToWebStream)(element, disable, options)));
}

@@ -79,141 +80,10 @@ injectToStream = result.injectToStream;

buffer.length = 0;
debug('promise `await renderToStream()` resolved');
(0, misc_1.debugFlow)('promise `await renderToStream()` resolved');
return result;
}
exports.renderToStream = renderToStream;
async function renderToNodeStream(element, disable, options) {
var _a;
debug('creating Node.js Stream Pipe');
let onAllReady;
const allReady = new Promise((r) => {
onAllReady = () => r();
});
let onShellReady;
const shellReady = new Promise((r) => {
onShellReady = () => r();
});
let didError = false;
let firstErr = null;
let reactBug = null;
const onError = (err) => {
debug('[react] onError() / onShellError()');
didError = true;
firstErr !== null && firstErr !== void 0 ? firstErr : (firstErr = err);
onShellReady();
afterReactBugCatch(() => {
var _a;
// Is not a React internal error (i.e. a React bug)
if (err !== reactBug) {
(_a = options.onBoundaryError) === null || _a === void 0 ? void 0 : _a.call(options, err);
}
});
};
const renderToPipeableStream = (_a = options.renderToPipeableStream) !== null && _a !== void 0 ? _a :
// We don't directly use import() because it shouldn't be bundled for Cloudflare Workers: the module react-dom/server.node contains a require('stream') which fails on Cloudflare Workers
(await (0, import_1.default)('react-dom/server.node')).renderToPipeableStream;
assertReactImport(renderToPipeableStream, 'renderToPipeableStream');
const { pipe: pipeOriginal } = renderToPipeableStream(element, {
onShellReady() {
debug('[react] onShellReady()');
onShellReady();
},
onAllReady() {
debug('[react] onAllReady()');
onShellReady();
onAllReady();
},
onShellError: onError,
onError
});
let promiseResolved = false;
const { pipeForUser, injectToStream, streamEnd } = await (0, createPipeWrapper_1.createPipeWrapper)(pipeOriginal, {
onReactBug(err) {
debug('react bug');
didError = true;
firstErr !== null && firstErr !== void 0 ? firstErr : (firstErr = err);
reactBug = err;
// Only log if it wasn't used as rejection for `await renderToStream()`
if (reactBug !== firstErr || promiseResolved) {
console.error(reactBug);
}
}
});
await shellReady;
if (didError)
throw firstErr;
if (disable)
await allReady;
if (didError)
throw firstErr;
promiseResolved = true;
return {
pipe: pipeForUser,
readable: null,
streamEnd: wrapStreamEnd(streamEnd, didError),
injectToStream
};
function renderToNodeStream_set(renderToNodeStream) {
globalObject.renderToNodeStream = renderToNodeStream;
}
async function renderToWebStream(element, disable, options) {
var _a;
debug('creating Web Stream Pipe');
let didError = false;
let firstErr = null;
let reactBug = null;
const onError = (err) => {
didError = true;
firstErr = firstErr || err;
afterReactBugCatch(() => {
var _a;
// Is not a React internal error (i.e. a React bug)
if (err !== reactBug) {
(_a = options.onBoundaryError) === null || _a === void 0 ? void 0 : _a.call(options, err);
}
});
};
const renderToReadableStream = (_a = options.renderToReadableStream) !== null && _a !== void 0 ? _a :
// We directly use import() because it needs to be bundled for Cloudflare Workers
(await import('react-dom/server.browser')).renderToReadableStream;
assertReactImport(renderToReadableStream, 'renderToReadableStream');
const readableOriginal = await renderToReadableStream(element, { onError });
const { allReady } = readableOriginal;
let promiseResolved = false;
// Upon React internal errors (i.e. React bugs), React rejects `allReady`.
// React doesn't reject `allReady` upon boundary errors.
allReady.catch((err) => {
debug('react bug');
didError = true;
firstErr = firstErr || err;
reactBug = err;
// Only log if it wasn't used as rejection for `await renderToStream()`
if (reactBug !== firstErr || promiseResolved) {
console.error(reactBug);
}
});
if (didError)
throw firstErr;
if (disable)
await allReady;
if (didError)
throw firstErr;
const { readableForUser, streamEnd, injectToStream } = (0, createReadableWrapper_1.createReadableWrapper)(readableOriginal);
promiseResolved = true;
return {
readable: readableForUser,
pipe: null,
streamEnd: wrapStreamEnd(streamEnd, didError),
injectToStream
};
}
// Needed for the hacky solution to workaround https://github.com/facebook/react/issues/24536
function afterReactBugCatch(fn) {
setTimeout(() => {
fn();
}, 0);
}
function wrapStreamEnd(streamEnd, didError) {
return (streamEnd
// Needed because of the `afterReactBugCatch()` hack above, otherwise `onBoundaryError` triggers after `streamEnd` resolved
.then(() => new Promise((r) => setTimeout(r, 0)))
.then(() => !didError));
}
exports.renderToNodeStream_set = renderToNodeStream_set;
// To debug wrong peer dependency loading:

@@ -228,5 +98,1 @@ // - https://stackoverflow.com/questions/21056748/seriously-debugging-node-js-cannot-find-module-xyz-abcd

}
function assertReactImport(fn, fnName) {
(0, utils_1.assert)(typeof fn === 'function');
(0, utils_1.assertUsage)(fn, `Couldn't import ${fnName}() from 'react-dom'`);
}

@@ -32,10 +32,9 @@ "use strict";

});
const { StreamContext } = globalObject;
const StreamProvider = StreamContext.Provider;
const StreamProvider = globalObject.StreamContext.Provider;
exports.StreamProvider = StreamProvider;
function useStream() {
const streamUtils = (0, react_1.useContext)(StreamContext);
(0, utils_1.assert)(streamUtils);
const streamUtils = (0, react_1.useContext)(globalObject.StreamContext);
(0, utils_1.assertUsage)(streamUtils, `react-streaming isn't installed`);
return streamUtils;
}
exports.useStream = useStream;
export declare function getGlobalObject<T extends Record<string, unknown> = never>(key: `${string}.ts`, defaultValue: T): T;
declare global {
var __react_streaming: undefined | Record<string, Record<string, unknown>>;
}

@@ -5,8 +5,10 @@ "use strict";

function getGlobalObject(
// We use the filename as key; each `getGlobalObject()` call should live in a unique filename.
// We use the filename as key; each `getGlobalObject()` call should live inside a file with a unique filename.
key, defaultValue) {
const allGlobalObjects = (globalThis.__react_streaming = globalThis.__react_streaming || {});
const globalObject = (allGlobalObjects[key] = allGlobalObjects[key] || defaultValue);
// @ts-ignore
const globalObjectsAll = (globalThis[projectKey] = globalThis[projectKey] || {});
const globalObject = (globalObjectsAll[key] = globalObjectsAll[key] || defaultValue);
return globalObject;
}
exports.getGlobalObject = getGlobalObject;
const projectKey = '_react_streaming';

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

export declare const projectInfo: {
export { projectInfo };
declare const projectInfo: {
projectName: "react-streaming";

@@ -7,4 +8,1 @@ projectVersion: string;

};
declare global {
var __vite_plugin_ssr__instances: undefined | string[];
}
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.projectInfo = void 0;
const PROJECT_VERSION = '0.3.18';
exports.projectInfo = {
const getGlobalObject_1 = require("./getGlobalObject");
const PROJECT_VERSION = '0.3.19-commit-20b3bc7';
const projectInfo = {
projectName: 'react-streaming',

@@ -11,4 +12,12 @@ projectVersion: PROJECT_VERSION,

};
// Trick: since `utils/asserts.ts` depends on this file (`utils/projectInfo.ts`), we can have confidence that this file is always instantiated. So that we don't have to initialize this code snippet at every possible entry. (There are a *lot* of entries: `client/router/`, `client/`, `node/`, `node/plugin/`, `node/cli`, etc.)
globalThis.__vite_plugin_ssr__instances = globalThis.__vite_plugin_ssr__instances || [];
globalThis.__vite_plugin_ssr__instances.push(exports.projectInfo.projectVersion);
exports.projectInfo = projectInfo;
const { versions } = (0, getGlobalObject_1.getGlobalObject)('projectInfo.ts', {
versions: new Set()
});
versions.add(projectInfo.projectVersion);
if (versions.size >= 2) {
const versionsStr = Array.from(versions)
.map((v) => `${projectInfo.projectName}@${v}`)
.join('and');
throw new Error(`Using different versions is forbidden, but ${versionsStr} are loaded. Make sure only one version is loaded.`);
}
export { renderToStream };
export { disable };
export { renderToNodeStream_set };
import React from 'react';
import type { renderToPipeableStream as RenderToPipeableStream, renderToReadableStream as RenderToReadableStream } from 'react-dom/server';
import { Pipe } from './renderToStream/createPipeWrapper';
import type { Pipe } from './renderToStream/createPipeWrapper';
import { SeoStrategy } from './renderToStream/resolveSeoStrategy';
import type { renderToNodeStream as RenderToNodeStream } from './renderToStream/renderToNodeStream';
declare type Options = {

@@ -29,1 +31,2 @@ webStream?: boolean;

declare function renderToStream(element: React.ReactNode, options?: Options): Promise<Result>;
declare function renderToNodeStream_set(renderToNodeStream: typeof RenderToNodeStream): void;
export { renderToStream };
export { disable };
export { renderToNodeStream_set };
import React from 'react';

@@ -7,9 +8,10 @@ import ReactDOMServer, { version as reactDomVersion } from 'react-dom/server';

import { StreamProvider } from './useStream';
import { createPipeWrapper } from './renderToStream/createPipeWrapper';
import { createReadableWrapper } from './renderToStream/createReadableWrapper';
import { resolveSeoStrategy } from './renderToStream/resolveSeoStrategy';
import { assert, assertUsage, createDebugger } from './utils';
import { assert, assertUsage, getGlobalObject } from './utils';
import { nodeStreamModuleIsAvailable } from './renderToStream/loadNodeStreamModule';
import import_ from '@brillout/import';
const debug = createDebugger('react-streaming:flow');
import { renderToWebStream } from './renderToStream/renderToWebStream';
import { debugFlow } from './renderToStream/misc';
const globalObject = getGlobalObject('renderToStream.ts', {
renderToNodeStream: null
});
assertReact();

@@ -37,7 +39,7 @@ const globalConfig = (globalThis.__react_streaming = globalThis

const webStream = (_b = options.webStream) !== null && _b !== void 0 ? _b : !(await nodeStreamModuleIsAvailable());
debug(`disable === ${disable} && webStream === ${webStream}`);
debugFlow(`disable === ${disable} && webStream === ${webStream}`);
let result;
const resultPartial = { disabled: disable };
if (!webStream) {
result = { ...resultPartial, ...(await renderToNodeStream(element, disable, options)) };
result = { ...resultPartial, ...(await globalObject.renderToNodeStream(element, disable, options)) };
}

@@ -50,140 +52,8 @@ else {

buffer.length = 0;
debug('promise `await renderToStream()` resolved');
debugFlow('promise `await renderToStream()` resolved');
return result;
}
async function renderToNodeStream(element, disable, options) {
var _a;
debug('creating Node.js Stream Pipe');
let onAllReady;
const allReady = new Promise((r) => {
onAllReady = () => r();
});
let onShellReady;
const shellReady = new Promise((r) => {
onShellReady = () => r();
});
let didError = false;
let firstErr = null;
let reactBug = null;
const onError = (err) => {
debug('[react] onError() / onShellError()');
didError = true;
firstErr !== null && firstErr !== void 0 ? firstErr : (firstErr = err);
onShellReady();
afterReactBugCatch(() => {
var _a;
// Is not a React internal error (i.e. a React bug)
if (err !== reactBug) {
(_a = options.onBoundaryError) === null || _a === void 0 ? void 0 : _a.call(options, err);
}
});
};
const renderToPipeableStream = (_a = options.renderToPipeableStream) !== null && _a !== void 0 ? _a :
// We don't directly use import() because it shouldn't be bundled for Cloudflare Workers: the module react-dom/server.node contains a require('stream') which fails on Cloudflare Workers
(await import_('react-dom/server.node')).renderToPipeableStream;
assertReactImport(renderToPipeableStream, 'renderToPipeableStream');
const { pipe: pipeOriginal } = renderToPipeableStream(element, {
onShellReady() {
debug('[react] onShellReady()');
onShellReady();
},
onAllReady() {
debug('[react] onAllReady()');
onShellReady();
onAllReady();
},
onShellError: onError,
onError
});
let promiseResolved = false;
const { pipeForUser, injectToStream, streamEnd } = await createPipeWrapper(pipeOriginal, {
onReactBug(err) {
debug('react bug');
didError = true;
firstErr !== null && firstErr !== void 0 ? firstErr : (firstErr = err);
reactBug = err;
// Only log if it wasn't used as rejection for `await renderToStream()`
if (reactBug !== firstErr || promiseResolved) {
console.error(reactBug);
}
}
});
await shellReady;
if (didError)
throw firstErr;
if (disable)
await allReady;
if (didError)
throw firstErr;
promiseResolved = true;
return {
pipe: pipeForUser,
readable: null,
streamEnd: wrapStreamEnd(streamEnd, didError),
injectToStream
};
function renderToNodeStream_set(renderToNodeStream) {
globalObject.renderToNodeStream = renderToNodeStream;
}
async function renderToWebStream(element, disable, options) {
var _a;
debug('creating Web Stream Pipe');
let didError = false;
let firstErr = null;
let reactBug = null;
const onError = (err) => {
didError = true;
firstErr = firstErr || err;
afterReactBugCatch(() => {
var _a;
// Is not a React internal error (i.e. a React bug)
if (err !== reactBug) {
(_a = options.onBoundaryError) === null || _a === void 0 ? void 0 : _a.call(options, err);
}
});
};
const renderToReadableStream = (_a = options.renderToReadableStream) !== null && _a !== void 0 ? _a :
// We directly use import() because it needs to be bundled for Cloudflare Workers
(await import('react-dom/server.browser')).renderToReadableStream;
assertReactImport(renderToReadableStream, 'renderToReadableStream');
const readableOriginal = await renderToReadableStream(element, { onError });
const { allReady } = readableOriginal;
let promiseResolved = false;
// Upon React internal errors (i.e. React bugs), React rejects `allReady`.
// React doesn't reject `allReady` upon boundary errors.
allReady.catch((err) => {
debug('react bug');
didError = true;
firstErr = firstErr || err;
reactBug = err;
// Only log if it wasn't used as rejection for `await renderToStream()`
if (reactBug !== firstErr || promiseResolved) {
console.error(reactBug);
}
});
if (didError)
throw firstErr;
if (disable)
await allReady;
if (didError)
throw firstErr;
const { readableForUser, streamEnd, injectToStream } = createReadableWrapper(readableOriginal);
promiseResolved = true;
return {
readable: readableForUser,
pipe: null,
streamEnd: wrapStreamEnd(streamEnd, didError),
injectToStream
};
}
// Needed for the hacky solution to workaround https://github.com/facebook/react/issues/24536
function afterReactBugCatch(fn) {
setTimeout(() => {
fn();
}, 0);
}
function wrapStreamEnd(streamEnd, didError) {
return (streamEnd
// Needed because of the `afterReactBugCatch()` hack above, otherwise `onBoundaryError` triggers after `streamEnd` resolved
.then(() => new Promise((r) => setTimeout(r, 0)))
.then(() => !didError));
}
// To debug wrong peer dependency loading:

@@ -198,5 +68,1 @@ // - https://stackoverflow.com/questions/21056748/seriously-debugging-node-js-cannot-find-module-xyz-abcd

}
function assertReactImport(fn, fnName) {
assert(typeof fn === 'function');
assertUsage(fn, `Couldn't import ${fnName}() from 'react-dom'`);
}
export { useStream };
export { StreamProvider };
import React, { useContext } from 'react';
import { assert, getGlobalObject } from './utils';
import { assertUsage, getGlobalObject } from './utils';
const globalObject = getGlobalObject('useStream.ts', {
StreamContext: React.createContext(null)
});
const { StreamContext } = globalObject;
const StreamProvider = StreamContext.Provider;
const StreamProvider = globalObject.StreamContext.Provider;
function useStream() {
const streamUtils = useContext(StreamContext);
assert(streamUtils);
const streamUtils = useContext(globalObject.StreamContext);
assertUsage(streamUtils, `react-streaming isn't installed`);
return streamUtils;
}
export declare function getGlobalObject<T extends Record<string, unknown> = never>(key: `${string}.ts`, defaultValue: T): T;
declare global {
var __react_streaming: undefined | Record<string, Record<string, unknown>>;
}
export function getGlobalObject(
// We use the filename as key; each `getGlobalObject()` call should live in a unique filename.
// We use the filename as key; each `getGlobalObject()` call should live inside a file with a unique filename.
key, defaultValue) {
const allGlobalObjects = (globalThis.__react_streaming = globalThis.__react_streaming || {});
const globalObject = (allGlobalObjects[key] = allGlobalObjects[key] || defaultValue);
// @ts-ignore
const globalObjectsAll = (globalThis[projectKey] = globalThis[projectKey] || {});
const globalObject = (globalObjectsAll[key] = globalObjectsAll[key] || defaultValue);
return globalObject;
}
const projectKey = '_react_streaming';

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

export declare const projectInfo: {
export { projectInfo };
declare const projectInfo: {
projectName: "react-streaming";

@@ -7,4 +8,1 @@ projectVersion: string;

};
declare global {
var __vite_plugin_ssr__instances: undefined | string[];
}

@@ -1,3 +0,5 @@

const PROJECT_VERSION = '0.3.18';
export const projectInfo = {
export { projectInfo };
import { getGlobalObject } from './getGlobalObject';
const PROJECT_VERSION = '0.3.19-commit-20b3bc7';
const projectInfo = {
projectName: 'react-streaming',

@@ -8,4 +10,11 @@ projectVersion: PROJECT_VERSION,

};
// Trick: since `utils/asserts.ts` depends on this file (`utils/projectInfo.ts`), we can have confidence that this file is always instantiated. So that we don't have to initialize this code snippet at every possible entry. (There are a *lot* of entries: `client/router/`, `client/`, `node/`, `node/plugin/`, `node/cli`, etc.)
globalThis.__vite_plugin_ssr__instances = globalThis.__vite_plugin_ssr__instances || [];
globalThis.__vite_plugin_ssr__instances.push(projectInfo.projectVersion);
const { versions } = getGlobalObject('projectInfo.ts', {
versions: new Set()
});
versions.add(projectInfo.projectVersion);
if (versions.size >= 2) {
const versionsStr = Array.from(versions)
.map((v) => `${projectInfo.projectName}@${v}`)
.join('and');
throw new Error(`Using different versions is forbidden, but ${versionsStr} are loaded. Make sure only one version is loaded.`);
}
{
"name": "react-streaming",
"description": "React 18 Streaming. Full-fledged & Easy.",
"version": "0.3.18",
"main": "./dist/cjs/server/hooks.js",
"version": "0.3.19-commit-20b3bc7",
"peerDependencies": {

@@ -15,2 +14,19 @@ "react": ">=18",

},
"main": "./dist/cjs/server/hooks.js",
"exports": {
".": {
"node": "./dist/cjs/server/hooks.js",
"worker": "./dist/esm/server/hooks.js",
"deno": "./dist/esm/server/hooks.js",
"browser": "./dist/esm/client/hooks.js",
"types": "./dist/cjs/server/hooks.d.ts"
},
"./server": {
"node": "./dist/cjs/server/index.node.js",
"worker": "./dist/esm/server/index.js",
"deno": "./dist/esm/server/index.js",
"browser": "./dist/esm/server/client-poison-pill.js",
"types": "./dist/cjs/server/index.d.ts"
}
},
"scripts": {

@@ -33,18 +49,2 @@ "// === Test ===": "",

},
"exports": {
".": {
"node": "./dist/cjs/server/hooks.js",
"worker": "./dist/esm/server/hooks.js",
"deno": "./dist/esm/server/hooks.js",
"browser": "./dist/esm/client/hooks.js",
"types": "./dist/cjs/server/hooks.d.ts"
},
"./server": {
"node": "./dist/cjs/server/index.js",
"worker": "./dist/esm/server/index.js",
"deno": "./dist/esm/server/index.js",
"browser": "./dist/esm/server/client-poison-pill.js",
"types": "./dist/cjs/server/index.d.ts"
}
},
"devDependencies": {

@@ -51,0 +51,0 @@ "@brillout/part-regex": "^0.1.2",

@@ -70,3 +70,3 @@ <p align="center">

> `react-streaming` makes it easy to build the libraries of tomorrow, for example:
> - Use [Telefunc](https://telefunc.com/) to easily fetch data for your Next.js app or your Vite + [`vite-plugin-ssr`](https://vite-plugin-ssr.com/) app. (Replacing Next.js's `getServerSideProps()` and `vite-plugin-ssr`'s `onBeforeRender()`.)
> - Use [Telefunc](https://telefunc.com) to fetch data for your Next.js or [Vike](https://vike.dev) app. (Instead of Next.js's `getServerSideProps()` / `Vike`'s `data()`.)
> - Better GraphQL tools, e.g. [Vilay](https://github.com/XiNiHa/vilay).

@@ -73,0 +73,0 @@

SocketSocket SOC 2 Logo

Product

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

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc