From 530d7209253d2e1aec55f61aaf29e3b243032425 Mon Sep 17 00:00:00 2001 From: SukkaW Date: Tue, 29 Aug 2023 13:33:34 +0800 Subject: [PATCH] feat: add `internal-slot` --- DOWNLOAD_STATS.md | 1 + create.cjs | 40 +++++++++++++++++++++++-- package.json | 2 ++ packages/cli/src/all-packages.ts | 1 + packages/internal-slot/index.js | 37 +++++++++++++++++++++++ packages/internal-slot/package.json | 19 ++++++++++++ packages/is-generator-function/index.js | 2 +- packages/side-channel/index.js | 2 +- pnpm-lock.yaml | 16 ++++------ 9 files changed, 105 insertions(+), 15 deletions(-) create mode 100644 packages/internal-slot/index.js create mode 100644 packages/internal-slot/package.json diff --git a/DOWNLOAD_STATS.md b/DOWNLOAD_STATS.md index 8e27b677..616f6d2a 100644 --- a/DOWNLOAD_STATS.md +++ b/DOWNLOAD_STATS.md @@ -32,6 +32,7 @@ | `@nolyfill/has-proto` | [![npm](https://img.shields.io/npm/dm/@nolyfill/has-proto.svg?style=flat-square&logo=npm&logoColor=white&label=download&color=333)](https://www.npmjs.com/package/@nolyfill/has-proto) | | `@nolyfill/has-symbols` | [![npm](https://img.shields.io/npm/dm/@nolyfill/has-symbols.svg?style=flat-square&logo=npm&logoColor=white&label=download&color=333)](https://www.npmjs.com/package/@nolyfill/has-symbols) | | `@nolyfill/has-tostringtag` | [![npm](https://img.shields.io/npm/dm/@nolyfill/has-tostringtag.svg?style=flat-square&logo=npm&logoColor=white&label=download&color=333)](https://www.npmjs.com/package/@nolyfill/has-tostringtag) | +| `@nolyfill/internal-slot` | [![npm](https://img.shields.io/npm/dm/@nolyfill/internal-slot.svg?style=flat-square&logo=npm&logoColor=white&label=download&color=333)](https://www.npmjs.com/package/@nolyfill/internal-slot) | | `@nolyfill/is-arguments` | [![npm](https://img.shields.io/npm/dm/@nolyfill/is-arguments.svg?style=flat-square&logo=npm&logoColor=white&label=download&color=333)](https://www.npmjs.com/package/@nolyfill/is-arguments) | | `@nolyfill/is-array-buffer` | [![npm](https://img.shields.io/npm/dm/@nolyfill/is-array-buffer.svg?style=flat-square&logo=npm&logoColor=white&label=download&color=333)](https://www.npmjs.com/package/@nolyfill/is-array-buffer) | | `@nolyfill/is-date-object` | [![npm](https://img.shields.io/npm/dm/@nolyfill/is-date-object.svg?style=flat-square&logo=npm&logoColor=white&label=download&color=333)](https://www.npmjs.com/package/@nolyfill/is-date-object) | diff --git a/create.cjs b/create.cjs index d9715e23..d04a8650 100644 --- a/create.cjs +++ b/create.cjs @@ -428,7 +428,7 @@ module.exports = function isGeneratorFunction(fn) { if (typeof fn !== 'function') return false; if (isFnRegex.test(Function.prototype.toString.call(fn))) return true; return Object.getPrototypeOf(fn) === GeneratorFunction; -}`], +};`], ['side-channel', `module.exports = () => { let $wm, $m; @@ -465,7 +465,43 @@ module.exports = function isGeneratorFunction(fn) { } }; return { get, set, has, assert }; -}`] +};`], + ['internal-slot', `const channel = new WeakMap(); +const check = (O, slot) => { + if (!O || (typeof O !== 'object' && typeof O !== 'function')) { + throw new TypeError('\`O\` is not an object'); + } + if (typeof slot !== 'string') { + throw new TypeError('\`slot\` must be a string'); + } +}; +const has = (O, slot) => { + check(O, slot); + const slots = channel.get(O); + return !!slots && Object.prototype.hasOwnProperty.call(slots, \`$\${slot}\`); +}; +const get = (O, slot) => { + check(O, slot); + const slots = channel.get(O); + return slots && slots[\`$\${slot}\`]; +}; +const set = (O, slot, V) => { + check(O, slot); + let slots = channel.get(O); + if (!slots) { + slots = {}; + channel.set(O, slots); + } + slots[\`$\${slot}\`] = V; +}; +const assert = (O, slot) => { + check(O, slot); + channel.assert(O); + if (!has(O, slot)) { + throw new TypeError(\`\\\`\${slot}\\\` is not present on \\\`O\\\`\`); + } +}; +module.exports = Object.freeze({ has, get, set, assert });`] ]); const manualPackagesList = /** @type {const} */ ([ diff --git a/package.json b/package.json index f25256d1..011307c7 100644 --- a/package.json +++ b/package.json @@ -63,6 +63,7 @@ "has-proto": "workspace:@nolyfill/has-proto@*", "has-symbols": "workspace:@nolyfill/has-symbols@*", "has-tostringtag": "workspace:@nolyfill/has-tostringtag@*", + "internal-slot": "workspace:@nolyfill/internal-slot@*", "is-arguments": "workspace:@nolyfill/is-arguments@*", "is-array-buffer": "workspace:@nolyfill/is-array-buffer@*", "is-date-object": "workspace:@nolyfill/is-date-object@*", @@ -146,6 +147,7 @@ "has-proto": "npm:@nolyfill/has-proto@latest", "has-symbols": "npm:@nolyfill/has-symbols@latest", "has-tostringtag": "npm:@nolyfill/has-tostringtag@latest", + "internal-slot": "npm:@nolyfill/internal-slot@latest", "is-arguments": "npm:@nolyfill/is-arguments@latest", "is-array-buffer": "npm:@nolyfill/is-array-buffer@latest", "is-date-object": "npm:@nolyfill/is-date-object@latest", diff --git a/packages/cli/src/all-packages.ts b/packages/cli/src/all-packages.ts index 04d64d84..3f5c7d25 100644 --- a/packages/cli/src/all-packages.ts +++ b/packages/cli/src/all-packages.ts @@ -31,6 +31,7 @@ export const allPackages = [ "has-proto", "has-symbols", "has-tostringtag", + "internal-slot", "is-arguments", "is-array-buffer", "is-date-object", diff --git a/packages/internal-slot/index.js b/packages/internal-slot/index.js new file mode 100644 index 00000000..f510925f --- /dev/null +++ b/packages/internal-slot/index.js @@ -0,0 +1,37 @@ +'use strict'; +const channel = new WeakMap(); +const check = (O, slot) => { + if (!O || (typeof O !== 'object' && typeof O !== 'function')) { + throw new TypeError('`O` is not an object'); + } + if (typeof slot !== 'string') { + throw new TypeError('`slot` must be a string'); + } +}; +const has = (O, slot) => { + check(O, slot); + const slots = channel.get(O); + return !!slots && Object.prototype.hasOwnProperty.call(slots, `$${slot}`); +}; +const get = (O, slot) => { + check(O, slot); + const slots = channel.get(O); + return slots && slots[`$${slot}`]; +}; +const set = (O, slot, V) => { + check(O, slot); + let slots = channel.get(O); + if (!slots) { + slots = {}; + channel.set(O, slots); + } + slots[`$${slot}`] = V; +}; +const assert = (O, slot) => { + check(O, slot); + channel.assert(O); + if (!has(O, slot)) { + throw new TypeError(`\`${slot}\` is not present on \`O\``); + } +}; +module.exports = Object.freeze({ has, get, set, assert }); diff --git a/packages/internal-slot/package.json b/packages/internal-slot/package.json new file mode 100644 index 00000000..07375829 --- /dev/null +++ b/packages/internal-slot/package.json @@ -0,0 +1,19 @@ +{ + "name": "@nolyfill/internal-slot", + "version": "1.0.19", + "repository": { + "type": "git", + "url": "https://github.com/SukkaW/nolyfill", + "directory": "packages/internal-slot" + }, + "main": "./index.js", + "license": "MIT", + "files": [ + "*.js" + ], + "scripts": {}, + "dependencies": {}, + "engines": { + "node": ">=12.4.0" + } +} diff --git a/packages/is-generator-function/index.js b/packages/is-generator-function/index.js index 790ff032..f2988ca4 100644 --- a/packages/is-generator-function/index.js +++ b/packages/is-generator-function/index.js @@ -6,4 +6,4 @@ module.exports = function isGeneratorFunction(fn) { if (typeof fn !== 'function') return false; if (isFnRegex.test(Function.prototype.toString.call(fn))) return true; return Object.getPrototypeOf(fn) === GeneratorFunction; -} +}; diff --git a/packages/side-channel/index.js b/packages/side-channel/index.js index 1c8f9d84..1fd6b711 100644 --- a/packages/side-channel/index.js +++ b/packages/side-channel/index.js @@ -35,4 +35,4 @@ module.exports = () => { } }; return { get, set, has, assert }; -} +}; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f6615ca6..d02007f1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -35,6 +35,7 @@ overrides: has-proto: workspace:@nolyfill/has-proto@* has-symbols: workspace:@nolyfill/has-symbols@* has-tostringtag: workspace:@nolyfill/has-tostringtag@* + internal-slot: workspace:@nolyfill/internal-slot@* is-arguments: workspace:@nolyfill/is-arguments@* is-array-buffer: workspace:@nolyfill/is-array-buffer@* is-date-object: workspace:@nolyfill/is-date-object@* @@ -383,6 +384,8 @@ importers: packages/internal: {} + packages/internal-slot: {} + packages/is-arguments: {} packages/is-array-buffer: @@ -2909,7 +2912,7 @@ packages: has-property-descriptors: link:packages/has-property-descriptors has-proto: link:packages/has-proto has-symbols: link:packages/has-symbols - internal-slot: 1.0.5 + internal-slot: link:packages/internal-slot is-array-buffer: link:packages/is-array-buffer is-callable: 1.2.7 is-negative-zero: 2.0.2 @@ -2949,7 +2952,7 @@ packages: has-property-descriptors: link:packages/has-property-descriptors has-proto: link:packages/has-proto has-symbols: link:packages/has-symbols - internal-slot: 1.0.5 + internal-slot: link:packages/internal-slot iterator.prototype: link:packages/iterator.prototype safe-array-concat: link:packages/safe-array-concat dev: true @@ -3643,15 +3646,6 @@ packages: engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} dev: true - /internal-slot@1.0.5: - resolution: {integrity: sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==} - engines: {node: '>= 0.4'} - dependencies: - get-intrinsic: 1.2.1 - has: link:packages/has - side-channel: link:packages/side-channel - dev: true - /ip@2.0.0: resolution: {integrity: sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==} dev: true