serialize-function 1.0.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -3
- package/lib/main.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,8 +1,19 @@
|
|
|
1
1
|
# serialize-function
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-

|
|
5
|
+
](https://github.com/EvanK/npm-serialize-function/actions/workflows/ci.yaml)
|
|
6
|
+
[
|
|
7
|
+

|
|
8
|
+
](https://nodejs.org/docs/latest-v20.x/api/)
|
|
9
|
+
[
|
|
10
|
+

|
|
11
|
+
](https://compat-table.github.io/compat-table/es2016plus/)
|
|
12
|
+
|
|
13
|
+
[
|
|
14
|
+

|
|
15
|
+
](https://www.npmjs.com/package/serialize-function)
|
|
16
|
+
|
|
6
17
|
|
|
7
18
|
## Quickstart
|
|
8
19
|
|
package/lib/main.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
async function digest(input){const hashBuffer=await window.crypto.subtle.digest("SHA-256",new TextEncoder().encode(input));return Array.from(new Uint8Array(hashBuffer)).map(item=>item.toString(16).padStart(2,"0")).join("")}class JsonError extends Error{};class CryptoError extends Error{};async function hasher(obj){let json,hashed;try{json=JSON.stringify(obj)}catch(cause){throw new JsonError("Failed to stringify serialized function structure",{cause})}try{hashed=await digest(json)}catch(cause){throw new CryptoError("Failed to generate hash digest",{cause})}return hashed}const AsyncFunction=async function(){}.constructor;const Generator=function*(){}.constructor;const AsyncGenerator=async function*(){}.constructor;const formatPatterns={"Generator":/^(async\s+)?function\*\s*[^()]*\(([^)]*)\)\s*{([\s\S]*)}$/,"Function":/^(async\s+)?function\s*[^()]*\(([^)]*)\)\s*{([\s\S]*)}$/,"ArrowFunction":/^(async\s+)?(?:\(([^)]*)\)|([^=\s(]+))\s*=>\s*(?:{([\s\S]*)}|([\s\S]+))$/};class SerializeError extends Error{}class DeserializeError extends Error{}class ChecksumError extends Error{}class ConstructError extends Error{}function getConstructor(type){switch(type){case"Function":case"ArrowFunction":return Function;case"AsyncFunction":case"AsyncArrowFunction":return AsyncFunction;case"Generator":return Generator;case"AsyncGenerator":return AsyncGenerator;default:throw new ConstructError(`Unexpected type ${type}`)}}function serialize(func,opts){const def={hash:false,comments:false,whitespace:false};opts=typeof opts==="object"&&null!==opts?Object.assign({},def,opts):Object.assign({},def);const typed=typeof func;if(typed!=="function"){throw new SerializeError("Invalid argument type, must be a function",{cause:{"typeof":typed}})}let stringified=func.toString();if(!opts.comments){stringified=stringified.replace(/\/\*[\s\S]*?\*\//g,"").replace(/\/\/.*$/gm,"")}if(!opts.whitespace){stringified=stringified.split(/[\r\n]+/).map(line=>line.trim()).filter(line=>line!=="").join("\n")}let match,serialized;for(const[type,pattern]of Object.entries(formatPatterns)){try{match=stringified.match(pattern);if(match){
|
|
1
|
+
async function digest(input){const hashBuffer=await window.crypto.subtle.digest("SHA-256",new TextEncoder().encode(input));return Array.from(new Uint8Array(hashBuffer)).map(item=>item.toString(16).padStart(2,"0")).join("")}class JsonError extends Error{};class CryptoError extends Error{};async function hasher(obj){let json,hashed;try{json=JSON.stringify(obj)}catch(cause){throw new JsonError("Failed to stringify serialized function structure",{cause})}try{hashed=await digest(json)}catch(cause){throw new CryptoError("Failed to generate hash digest",{cause})}return hashed}const AsyncFunction=async function(){}.constructor;const Generator=function*(){}.constructor;const AsyncGenerator=async function*(){}.constructor;const formatPatterns={"Generator":/^(async\s+)?function\*\s*[^()]*\(([^)]*)\)\s*{([\s\S]*)}$/,"Function":/^(async\s+)?function\s*[^()]*\(([^)]*)\)\s*{([\s\S]*)}$/,"ArrowFunction":/^(async\s+)?(?:\(([^)]*)\)|([^=\s(]+))\s*=>\s*(?:{([\s\S]*)}|([\s\S]+))$/};class SerializeError extends Error{}class DeserializeError extends Error{}class ChecksumError extends Error{}class ConstructError extends Error{}function getConstructor(type){switch(type){case"Function":case"ArrowFunction":return Function;case"AsyncFunction":case"AsyncArrowFunction":return AsyncFunction;case"Generator":return Generator;case"AsyncGenerator":return AsyncGenerator;default:throw new ConstructError(`Unexpected type ${type}`)}}function serialize(func,opts){const def={hash:false,comments:false,whitespace:false};opts=typeof opts==="object"&&null!==opts?Object.assign({},def,opts):Object.assign({},def);const typed=typeof func;if(typed!=="function"){throw new SerializeError("Invalid argument type, must be a function",{cause:{"typeof":typed}})}let stringified=func.toString();if(!opts.comments){stringified=stringified.replace(/\/\*[\s\S]*?\*\//g,"").replace(/\/\/.*$/gm,"")}if(!opts.whitespace){stringified=stringified.split(/[\r\n]+/).map(line=>line.trim()).filter(line=>line!=="").join("\n")}let match,serialized;for(const[type,pattern]of Object.entries(formatPatterns)){try{match=stringified.match(pattern);if(match){let async=match[1]?"Async":"";let params=type==="ArrowFunction"?match[2]??match[3]:match[2];params=params.split(",").map(p=>opts.whitespace?p:p.trim()).filter(Boolean);let body=type==="ArrowFunction"?match[4]??`return (${match[5]});`:match[3];if(!opts.whitespace)body=body.trim();serialized={params,body,type:`${async}${type}`};break}}catch(cause){throw new SerializeError(`Unexpected error serializing ${type}`,{cause})}}if(!serialized){throw new SerializeError("Unsupported function format",{cause:stringified})}if(opts.hash){return hasher(serialized).then(hashed=>{serialized.hash=hashed;return serialized}).catch(cause=>{throw new SerializeError("Failure hashing serialized function",{cause})})}return serialized}function deserialize(struct){let opts=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{hash:false};if(opts?.hash){if(struct?.hash===undefined){throw new DeserializeError("Deserialized function missing hash")}const test=Object.assign({},struct);delete test.hash;return hasher(test).then(checksum=>{if(checksum!==struct.hash){throw new ChecksumError("Checksum failed",{cause:{a:checksum,b:struct.hash}})}return deserialize(struct,{hash:false})}).catch(cause=>{if(cause instanceof ChecksumError||cause instanceof DeserializeError||cause instanceof ConstructError){throw cause}throw new DeserializeError("Failure generating checksum",{cause})})}try{const constructor=getConstructor(struct.type);return new constructor(...struct.params,struct.body)}catch(cause){if(cause instanceof ConstructError)throw cause;throw new DeserializeError("Failure deserializing",{cause})}}export{serialize,deserialize};
|