Serialize arbitrary NodeJS closures and customize serialization behavior.

Overview

Closure Serializer

This is a fork of the Pulumi Closure Serializer. @pulumi/pulumi.

Motivation

Functionless allows developers to write cloud applications (using aws-cdk) with pure typescript.

const sfn = new StepFunction(stack, 'sfn', () => {
   /* something in the state machine */
   return "result";
});

new Function(stack, 'func', async () => {
    return sfn();
})

More on Function in the doc: https://functionless.org/docs/concepts/function

Pulumi's closure serializer helped us bootstrap this experience by doing the heavy lifting of runtime data serialization.

However, Pulumi's serializer had a few short comings:

  1. Coupled to the whole @pulumi/pulumi npm package
  2. Limited extensibility
  3. Makes use of Pulumi resources (Logging and Secrets) in the serializer

Changes from Pulumi

  • Bug Fix: Symbol Support
  • Removed: Pulumi Secret support
  • Removed: Pulumi Logging support
  • Change: serialize function support replacement of runtime data to be serialized on top of avoiding serialization

Forked from

https://github.com/pulumi/pulumi/releases/tag/v3.33.2

Comments
  • feat: support transforming AST of serialized closure

    feat: support transforming AST of serialized closure

    Closes https://github.com/functionless/nodejs-closure-serializer/issues/13 Closes https://github.com/functionless/nodejs-closure-serializer/issues/15

    • [x] Allows a list of TS AST transformers to be passed in to serializeFunction that will be applied to a closure before serialization.
    • [x] Updates all tests cases to actually run the closures and ensure the returned value is correct.
    • [x] Replace use of with with closured constants for enhanced performance

    BREAKING CHANGE: with statement replaced with const statements in the closure. Potentially unintended breaking behavior not covered by the unit tests. Should be adopted purposefully.

    opened by sam-goodwin 1
  • fix: ignore $jsDebugIsRegistered

    fix: ignore $jsDebugIsRegistered

    Strange bug where vs code (and other test tools) set a global["$jsDebugIsRegistered"] with a getter that, when called, throws an exception. This change is a quick hack to ignore serializing that property - it should never impact prod.

    opened by sam-goodwin 0
  • feat: add hook for excluding specific properties from serialization

    feat: add hook for excluding specific properties from serialization

    • [x] adds a shouldCaptureProp hook for excluding properties from serialization.
    serializeFunction({
      shouldCaptureProp: (obj, prop) => typeof obh === "function" && prop === "bad name"
    });
    
    • [x] when transforming closures, unwrap a ExpressionStatement(ParenthesizedExpression(FunctionExpression)) to a single FunctionExpression
    opened by sam-goodwin 0
  • Support transforming AST prior to serialization

    Support transforming AST prior to serialization

    It should be possible to transform the AST syntax prior to serialization rather than relying purely on value-level serialization customization.

    This would be useful for removing syntax added by Functionless's TS transformers.

    opened by sam-goodwin 0
  • `with` degrades performance significantly

    `with` degrades performance significantly

    The way the closure serializer wraps closures in a with degrades performance by approximately 4-5x. See below for an example.

    function foo() {
      with({
        a: "hello"
      }) {
        return (function() {
          return function() {
            return arguments * 10 ;
          }
        }).apply(undefined, undefined).apply(this, arguments);
      }
    }
    
    
    function foo2() {
      return (function() {
        return function() {
          return arguments * 10;
        }
      }).apply(undefined, undefined).apply(this, arguments)
    }
    
    for (let j = 0; j < 10; j++) {
      const start = new Date();
      for (let i = 0; i < 10*1000*1000; i++) {
        foo2(i);
      }
      
      console.log(new Date().getTime() - start.getTime());
    }
    
    opened by sam-goodwin 0
  • feat: allow for injected functions

    feat: allow for injected functions

    Allows for the serialize function to accept Function expr or Arrow Expr and return values.

    previously serialize would throw an error when a function was returned.

    opened by thantos 0
  • feat: do not serialize functions or constructors that are not invoked.

    feat: do not serialize functions or constructors that are not invoked.

    class C {
       static S = "x"
       constructor() {}
    }
    
    () => {
       // does not need the whole class
       C.S
    }
    
    () => {
       // needs the whole class
       new C()
    }
    
    () => {
       // needs the whole class
       C.S
       new C();
    }
    
    () => {
       // needs the whole class
       const doSomething = (d: any) => {}
       doSomething(C);
    }
    
    opened by thantos 0
  • feat: v2 of the closure serializer

    feat: v2 of the closure serializer

    Total re-write of the closure serializer as a single recursive pass.

    For visual context, refer to this diagram of Prototypical Inheritance: image

    Outstanding tasks:

    • [ ] support recursive references in properties
    • [ ] serialize classes as Functions (not classes)
    • [ ] detect augmented globals
    • [ ] detect references to modules or a module's exports and emit as an import/require
    • [ ] run esbuild on the serialized closure + imports to create a tree-shaken bundle with minimal usage of the closure serializer and maximal usage of esbuild
    opened by sam-goodwin 0
  • Maintain references to closured `let` and `var`

    Maintain references to closured `let` and `var`

    Closure serialization should maintain references to closured let and var and all modifications of that value should reflect everywhere it is referenced.

    Below is a test case that should pass, with expectResult: 2, but the result is 0 - because the closured let is re-declared in each closure and copied by-value, not by-ref. This is true even when using the previous with technique.

    let i = 0;
    function a() {
      i += 1;
    }
    function b() {
      i += 1;
    }
    
    cases.push({
      title: "two functions modifying a single let have changes reflected",
      func: () => {
        a();
        b();
        return i;
      },
      snapshot: true,
      expectResult: 2,
    });
    
    bug 
    opened by sam-goodwin 0
  • Support configuration pattern based matching for deploymentOnlyModule

    Support configuration pattern based matching for deploymentOnlyModule

    From https://github.com/functionless/functionless/pull/273

    It would be nice to remove the deploymentOnlyModule from the bottom of all of the files. By passing in a pattern to the serialize function, we could avoiding missing files and polluting the modules.

    opened by thantos 0
  • Support outputting esmodule format

    Support outputting esmodule format

    For https://github.com/functionless/functionless/issues/274

    • [ ] Output import and export instead of require and exports.
    • [ ] support top level async
    • [ ] Generated imports should support tree shaking
    opened by thantos 0
  • Update the serialize contract

    Update the serialize contract

    The repo is a fork of @pulumi/pulumi's closure serializer.

    One of the changes to the original repo was to support replacement of objects to be serialized using the serialize callback.

    The current implementation supports the contract (o: any) => boolean | any where:

    • true - serialize o as is - original contract
    • false - do not serialize o (replace with undefined) - original contract
    • anything else - replace o with the value

    This contract isn't great, but it was a quick update from the original contract.

    We should update this to support the edge case where a boolean value should replace the original value.

    Proposal:

    /**
     * return the value to serialize, return `undefined` to skip serialization. `undefined` may also be used to avoid circular references.
     **/
    serialize: (o: any) => any | undefined
    

    In the updated contract, the user just returns the new value or current value.

    opened by thantos 0
Releases(v0.1.5)
Owner
null
Serialize and deserialize any object and all of its references 🥣

Super Cereal ?? Serialize and deserialize any object and all of its references. Supports: Class (with inheritance set-up) Object Array Function Map Se

Seb Ringrose 5 Nov 1, 2022
Serialize an HTML Form to a JavaScript Object, supporting nested attributes and arrays.

jquery.serializeJSON Adds the method .serializeJSON() to jQuery to serializes a form into a JavaScript Object. Supports the same format for nested par

Mario Izquierdo 1.7k Dec 12, 2022
Binary-encoded serialization of JavaScript objects with generator-based parser and serializer

YaBSON Schemaless binary-encoded serialization of JavaScript objects with generator-based parser and serializer This library is designed to transfer l

Gildas 11 Aug 9, 2022
A good web interface for youtube-dl that allows you to download arbitrary mixes of audio and video, including up to the highest quality such as 8K.

?? youtube-dl-web A good web interface for youtube-dl that allows you to download arbitrary mixes of audio and video, including up to the highest qual

Codian 90 Dec 30, 2022
A RESP 'Redis Serialization Protocol' library implementation to generate a server, uses a similar approach to express to define you serer, making it easy and fast.

RESPRESS A RESP 'Redis Serialization Protocol' library implementation to generate a server, uses a similar approach to express to define you serer, ma

Yousef Wadi 9 Aug 29, 2022
Glorious Binary Serialization and Deserialization for TypeScript.

Glorious SerDes for TypeScript The library you can rely on, For binary serialization and deserialization, In Node, Deno, and the Web environment, Whic

Wei 25 Dec 11, 2022
A vanilla-js module for adding zoom-on-wheel and pan-on-drag behavior to inline SVG elements.

svg-pan-zoom-container A vanilla-js module for adding zoom-on-wheel and pan-on-drag behavior to inline SVG elements. No need to write scripts. Just ma

31 Dec 10, 2022
🚀AI拟声: 5秒内克隆您的声音并生成任意语音内容 Clone a voice in 5 seconds to generate arbitrary speech in real-time

English | 中文 Features ?? Chinese supported mandarin and tested with multiple datasets: aidatatang_200zh, magicdata, aishell3, and etc. ?? PyTorch work

Vega 25.6k Dec 29, 2022
Serialization library for data-oriented design structures in JavaScript

Data-oriented Serialization for SoA/AoA A zero-dependency serialization library for data-oriented design structures like SoA (Structure of Arrays) and

null 11 Sep 27, 2022
superserial provides serialization in any way you can imagine.

superserial After data transfer, when the object needs to be restored, JSON has many limitations. It does not support values such as Infinity and NaN,

DenoStack 24 Dec 23, 2022
⛑️ JSON serialization should never fail

⛑️ JSON serialization should never fail. Features Prevent JSON.serialize() from: Throwing Changing types Filtering or transforming values unexpectedly

ehmicky 191 Dec 15, 2022
Render arbitrary Markdown content in Astro, optionally integrating with any existing configuration.

Astro Markdown Astro Markdown lets you render arbitrary Markdown content in Astro, optionally integrating with any existing configuration. --- import

Astro Community 14 Dec 22, 2022
Forked from hayes0724/shopify-packer Modern development tool for Shopify using Webpack 5. Easy to extend and customize, zero build config, compatible with Slate and existing websites.

Shopify Packer Modern development tool for Shopify using Webpack 5. Easy to extend and customize, zero build config, comes with starter themes and com

Web & Mobile | eCommerce | Full-Stack Developer 4 Nov 24, 2022
A Meme generator website where you can change and customize images to create great memes😎.

App Screenshot: Getting Started with Create React App This project was bootstrapped with Create React App. Available Scripts In the project directory,

Harsh Jain 7 Dec 21, 2022
Easily open daily notes and periodic notes in new pane; customize periodic notes background; quick append new line to daily notes.

Obsidian daily notes opener This plugin adds a command for opening daily notes in a new pane (so that a keyboard shortcut could be used!) and gives ex

Xiao Meng 16 Dec 26, 2022
Salazar - a Discord bot that is easy to customize and configure, aiming at the possibility of customization for the user

Salazar is a Discord bot that is easy to customize and configure, aiming at the possibility of customization for the user. This is the BETA version, which uses the current version of Node.js.

guto 5 Dec 7, 2022
Custom alert box using javaScript and css. This plugin will provide the functionality to customize the default JavaScript alert box.

customAlertBoxPlugin Custom Alert Box Plugin Using JavaScript and CSS Author: Suraj Aswal Must Include CSS Code/Default Custom Alert Box Class: /* mus

Suraj Aswal 17 Sep 10, 2022
Create, Customize and Commit your project's ReadMe in VS Code with an integrated extension

VS Code Readme Editor ?? A VS Code extension to create, customize and save your Readme without having to leave your project workspace. Built with Type

Sumit Nalavade 22 Dec 29, 2022
A simple editor allows you to easily add and customize all the sections you need for your profile's readme.

Create your Profile README using the best Templates tomper-readmify.herokuapp.com This is the frontend + backend of TomperReadmify build with MERN sta

Varun Tiwari 15 Jan 2, 2023