Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@webqit/subscript

Package Overview
Dependencies
Maintainers
1
Versions
92
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@webqit/subscript - npm Package Compare versions

Comparing version 2.0.7 to 2.0.8

dist/console-element.js

2

package.json

@@ -11,3 +11,3 @@ {

"homepage": "https://webqit.io/tooling/subscript",
"version": "2.0.7",
"version": "2.0.8",
"license": "MIT",

@@ -14,0 +14,0 @@ "repository": {

@@ -11,23 +11,12 @@ # Subscript

\> Install via npm
+ [What's A Dependency Thread?](#whats-a-dependency-thread)
+ [What Is Subscript?](#whats-subscript)
+ [Concepts](#concepts)
+ [Motivation](#motivation)
+ [Installation](#installation)
+ [API](#api)
```cmd
npm i @webqit/subscript
```
```js
import SubscriptFunction from '@webqit/subscript';
```
\> Include from a CDN
```html
<script src="https://unpkg.com/@webqit/subscript/dist/main.js"></script>
```
```js
const SubscriptFunction = WebQit.Subscript;
```
## What's A Dependency Thread?
That's simply the line of dependencies involving two or more expressions.
That's simply the dependency chain involving two or more JavaScript expressions.

@@ -179,6 +168,2 @@ ```js

+ [Concepts](#concepts)
+ [API](#api)
+ [Why Subscript](#why-subscript)
## Concepts

@@ -560,2 +545,152 @@

[TODO]
## Motivation
[TODO]
## Installation
\> Install via npm
```cmd
npm i @webqit/subscript
```
```js
import SubscriptFunction from '@webqit/subscript';
```
\> Include from a CDN
```html
<script src="https://unpkg.com/@webqit/subscript/dist/main.js"></script>
```
```js
const SubscriptFunction = WebQit.Subscript;
```
## API
`SubscriptFunction` is a one-to-one equivalent of the [JavaScript function constructor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/Function). You can just use them interchangeably 😎.
### Syntax
```js
// Statically
let subscrFunction = SubscriptFunction( functionBody );
let subscrFunction = SubscriptFunction( arg1, functionBody );
let subscrFunction = SubscriptFunction( arg1, ... argN, functionBody );
// With the new keyword
let subscrFunction = new SubscriptFunction( functionBody );
let subscrFunction = new SubscriptFunction( arg1, functionBody );
let subscrFunction = new SubscriptFunction( arg1, ... argN, functionBody );
```
### Parameters
#### `arg1, ... argN`
Names to be used by the function as formal argument names. Each must be a string that corresponds to a valid JavaScript parameter (any of plain identifier, rest parameter, or destructured parameter, optionally with a default), or a list of such strings separated with commas.
#### `functionBody`
A string that represents the function body.
### Return Value
A regular `Function` object, or an `async function` object where the `await` keyword is used within `functionBody`.
```js
// Create a regular function - sum
let sum = SubscriptFunction( 'a', 'b', 'return a + b;' );
// Call the returned sum function and log the result
console.log( sum( 10, 2 ) );
< 12
```
```js
// Create an async function - sum
let sum = SubscriptFunction( 'a', 'b', 'return a + await b;' );
// Call the returned sum function and log the result
sum( 10, 2 ).then( result => {
console.log( result );
} );
< 12
```
### The `this` Binding
Functions returned by `SubscriptFunction` are standard functions that can have their own [`this`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this) binding at *call time*.
```js
// Create a function - colorSwitch - that sets a DOM element's color
let colorSwitch = SubscriptFunction( 'color', 'this.style.color = color;' );
// Call colorSwitch, with document.body as it's this binding
let element = document.body;
colorSwitch.call( element, 'red' );
```
But, where the `this` binding is `undefined` at call time, the `this` binding of the `SubscriptFunction` itself is used. This lets us have a default `this` binding at *creation time*.
```js
// Create the same colorSwitch, this time, with a this binding that can be used at call time
let element = document.body;
let colorSwitch = SubscriptFunction.call( element, 'color', 'this.style.color = color;' );
// Call colorSwitch, without a this binding
colorSwitch( 'red' );
colorSwitch.call( undefined, 'red' );
// Call colorSwitch, with a different this binding
let h1Element = document.getElementById( 'h1' );
colorSwitch.call( h1Element, 'red' );
```
### The `subscrFunction.signal()` Method
The `.signal()` method is the *reactivity* API in Subscript functions that lets us send *change signals* into the *reactivity runtime*. It takes a list of the outside variables or properties that have changed; each as an array path.
#### Syntax
```js
let returnValue = subscrFunction.signal( path1, ... pathN );
```
#### Parameters
##### `path1, ... pathN`
An array path representing each variable, or object property, that has changed. *See [Signals](#signals) for concepts and usage.*
#### Return Value
The return value of this method depends on the return value of the *dependency thread* it initiates within the function body.
```js
// Global variables to use
a = 10;
b = 2;
// Create a function with two possible values
let sum = SubscriptFunction(`
if ( a > 10 ) {
return a + await b;
}
return a + b;
`);
// Run normally
console.log( sum() );
< 12
// Run a thread with a different return value
a = 20;
console.log( sum.signal( [ 'a' ] ) );
< Promise { 22 }
```
## Documentation

@@ -562,0 +697,0 @@

@@ -53,2 +53,13 @@

const _returns = ( ...__nodes ) => _nodes.concat( __nodes );
const _visit = ( _node, _effect = effect ) => Object.keys( _node ).reduce( ( __node, key ) => {
let value = _node[ key ];
if ( value && value.type === 'Identifier' ) {
_effect.subscriptIdentifiersNoConflict( value );
} else if ( Array.isArray( value ) ) {
value = value.map( v => _visit( v ) );
} else if ( typeof value === 'object' && value ) {
value = _visit( value );
}
return { ...__node, [ key ]: value };
}, {} );
if ( !node ) return _returns( node );

@@ -71,2 +82,21 @@

* ------------
* #ArrowFunctionExpression
* #FunctionExpression
* #FunctionDeclaration
* ------------
*/
if ( node.type === 'ArrowFunctionExpression' || node.type === 'FunctionExpression' || node.type === 'FunctionDeclaration' ) {
let createNode = astNodes[ node.type === 'ArrowFunctionExpression' ? 'arrowFuncExpr' : (
node.type === 'FunctionExpression' ? 'funcExpr' : 'funcDeclaration'
) ].bind( astNodes );
if ( node.type === 'FunctionDeclaration' ) {
node = _visit( node, scope.ownerEffect );
} else {
node = _visit( node, effect );
}
return _returns( node );
}
/**
* ------------
* #VariableDeclaration

@@ -334,15 +364,19 @@ * ------------

if ( node.type === 'ReturnStatement' ) {
let [ argument ] = _transform( [ node.argument ], scope.currentEffect || scope.ownerEffect /* This is a statement that could have had its own effect */ );
if ( scope.static() || !scope.currentEffect ) {
if ( scope.static() && 0 ) {
let [ argument ] = _transform( [ node.argument ], scope.currentEffect || scope.ownerEffect /* This is a statement that could have had its own effect */ );
return _returns( astNodes.returnStmt( argument ) );
}
let subscript$construct = astNodes.identifier( scope.currentEffect.getSubscriptIdentifier( '$construct', true ) );
let keyword = astNodes.literal( 'return' );
let arg = argument || astNodes.identifier( 'undefined' );
let exitCall = astNodes.exprStmt(
astNodes.callExpr( astNodes.memberExpr( subscript$construct, astNodes.identifier( 'exit' ) ), [ keyword, arg ] ),
);
// Return statement hoisting
scope.currentEffect.hoistExitStatement( keyword, astNodes.identifier( 'true' ) );
return _returns( exitCall, astNodes.returnStmt() );
let def = { type: node.type };
return scope.createEffect( def, effect => {
let [ argument ] = effect.causesProduction( def, () => _transform( [ node.argument ], effect ) );
let subscript$construct = astNodes.identifier( effect.getSubscriptIdentifier( '$construct', true ) );
let keyword = astNodes.literal( 'return' );
let arg = argument || astNodes.identifier( 'undefined' );
let exitCall = astNodes.exprStmt(
astNodes.callExpr( astNodes.memberExpr( subscript$construct, astNodes.identifier( 'exit' ) ), [ keyword, arg ] ),
);
// Return statement hoisting
effect.hoistExitStatement( keyword, astNodes.identifier( 'true' ) );
return _returns( ...effect.compose( [ exitCall, astNodes.returnStmt() ] ) );
} );
}

@@ -558,5 +592,7 @@

let production = effect.currentProduction;
do {
production.addRef().unshift( $identifier );
} while( production = production.contextProduction );
if ( production ) {
do {
production.addRef().unshift( $identifier );
} while( production = production.contextProduction );
}
}

@@ -568,33 +604,2 @@ return _returns( createNode() );

* ------------
* #ArrowFunctionExpression
* #FunctionExpression
* #FunctionDeclaration
* ------------
*/
if ( node.type === 'ArrowFunctionExpression' || node.type === 'FunctionExpression' || node.type === 'FunctionDeclaration' ) {
let createNode = astNodes[ node.type === 'ArrowFunctionExpression' ? 'arrowFuncExpr' : (
node.type === 'FunctionExpression' ? 'funcExpr' : 'funcDeclaration'
) ].bind( astNodes );
let [ id ] = node.type === 'FunctionDeclaration'
? effect.noSelect( () => _transform( [ node.id ] ) )
: [ node.id ];
let params = node.params.map( param => {
if ( param.type !== 'AssignmentExpression' ) return param;
let [ right ] = effect.noSelect( () => _transform( [ param.right ] ) );
return astNodes.assignmentExpr( param.left, right, param.operator );
} );
let body, functionScope = ( new Scope( null, { type: 'Function' } ) ).static( true );
if ( node.body.type === 'BlockStatement' ) {
let statements = _transform( node.body.body, null, functionScope );
body = astNodes.blockStmt( statements );
} else {
[ body ] = _transform( [ node.body ], null, functionScope );
}
return _returns(
createNode( params, body, node.async, id, node.expression, node.generator )
);
}
/**
* ------------
* #Other

@@ -601,0 +606,0 @@ * ------------

@@ -212,2 +212,5 @@

this.causes.unshift( causesProduction );
if ( def.static ) {
resolveInScope = false;
}
return this._runProduction( causesProduction, callback, resolveInScope );

@@ -219,2 +222,5 @@ }

this.affecteds.unshift( affectedsProduction );
if ( def.static ) {
resolveInScope = false;
}
return this._runProduction( affectedsProduction, callback, resolveInScope );

@@ -230,15 +236,13 @@ }

embeddableCausesProduction( def, callback ) {
let result = this.causesProduction( def, ( production, currentProduction ) => {
return this.causesProduction( def, ( production, currentProduction ) => {
production.contextProduction = currentProduction;
return callback( production, currentProduction );
} );
return result;
}
embeddableAffectedsProduction( def, callback ) {
let result = this.affectedsProduction( def, ( production, currentProduction ) => {
return this.affectedsProduction( def, ( production, currentProduction ) => {
production.contextProduction = currentProduction;
return callback( production, currentProduction );
} );
return result;
}

@@ -419,6 +423,7 @@

get isIntermediateInstance() {
return this.type === 'BlockStatement'
|| ( this.type === 'LabeledStatement' && this.scopes.length );
return this.type === 'BlockStatement' || this.type === 'FunctionDeclaration' || (
this.type === 'LabeledStatement' && this.scopes.length
);
}
}

@@ -39,2 +39,3 @@

assignmentExpr( left, right, operator = '=' ) { return { type: 'AssignmentExpression', operator, left, right }; },
assignmentPattern( left, right ) { return { type: 'AssignmentPattern', left, right }; },
thisExpr() { return { type: 'ThisExpression' }; },

@@ -41,0 +42,0 @@ condExpr( test, consequent, alternate, type = 'ConditionalExpression' ) { return { type, test, consequent, alternate }; },

@@ -183,3 +183,3 @@

this._textarea.placeholder = newValue;
break
break;
case 'editable':

@@ -195,2 +195,3 @@ this._editable = newValue;

}
break;
}

@@ -221,5 +222,5 @@ }

display: block;
/* Normal inline styles */
font-size: 0.8rem;

@@ -264,3 +265,2 @@ font-family: monospace;

textarea, pre {

@@ -276,3 +276,2 @@ /* In the same place */

/* Move the textarea in front of the result */

@@ -287,3 +286,2 @@

/* Make textarea almost completely transparent */

@@ -290,0 +288,0 @@

@@ -40,3 +40,3 @@

`
.ref-identifier:is(.path-hover, .path-runtime-active) {
.ref-identifier.path-runtime-active {
text-decoration: underline;

@@ -64,2 +64,3 @@ }

color: yellowgreen;
text-decoration: underline;
}

@@ -87,2 +88,9 @@

}
}
/**
* @define
*/
customElements.define( 'subscript-codeblock', CodeBlock() );
customElements.define( 'subscript-effect', Effect );
customElements.define( 'subscript-console', Console );

@@ -5,11 +5,4 @@

*/
import CodeBlock from './CodeBlock.js';
import Console from './Console.js';
import Effect from './Effect.js';
/**
* @define
*/
customElements.define( 'subscript-codeblock', CodeBlock() );
customElements.define( 'subscript-console', Console );
customElements.define( 'subscript-effect', Effect );
import './Console.js';
import './Inspector.js';
import './Player.js';

@@ -41,3 +41,3 @@

subscriptElement.subscriptConsole.forEach( ( subscriptFunction, id ) => {
let title = typeof id === 'number' ? `<${ id }>()` : `${ id }()`;
let title = typeof id === 'number' ? `script:${ id }` : `${ id }()`;
this.buttons[ id ] = this.controlsElement.appendChild( document.createElement( 'button' ) );

@@ -49,3 +49,3 @@ this.buttons[ id ].setAttribute( 'script-id', id );

let iconElement = this.buttons[ id ].appendChild( document.createElement( 'i' ) );
let iconClasses = this.getAttribute( `data-icons` ) || `bi bi-braces`;
let iconClasses = this.getAttribute( `data-icons` ) || `bi bi-${ typeof id === 'number' ? 'code' : 'braces' }`;
iconClasses.split( ' ' ).map( str => str.trim() ).forEach( str => iconElement.classList.add( str ) );

@@ -125,2 +125,5 @@ this.buttons[ id ].addEventListener( 'click', e => {

/**
* @define
*/
customElements.define( 'subscript-inspector', Inspector );

@@ -136,2 +136,5 @@

/**
* @define
*/
customElements.define( 'subscript-player', Player );

@@ -42,3 +42,5 @@

let callee = arg1;
let childEffect = new Effect( this, effectGraph, callee, { ...this.params }, this.exits );
let firstChild = effectGraph.childEffects[ Object.keys( effectGraph.childEffects )[ 0 ] ],
isFunctionExpression = firstChild && firstChild.type === 'FunctionExpression';
let childEffect = new Effect( this, effectGraph, callee, { ...this.params, isFunctionExpression }, isFunctionExpression ? null : this.exits );
if ( this.childEffects.has( effectId ) ) {

@@ -67,3 +69,3 @@ this.childEffects.get( effectId ).dispose();

let ret = this.callee.call( $this, this.construct, ...$arguments );
if ( !this.parentEffect ) {
if ( !this.parentEffect || this.params.isFunctionExpression ) {
let _ret = this.exits.get( 'return' );

@@ -82,6 +84,6 @@ this.exits.clear();

let [ [ /* iterationEffectId */, iterationInstances ] ] = this.childEffects;
let prev, after = ( prev, callback ) => prev instanceof Promise ? prev.then( callback ) : callback();
let prev, _await = ( prev, callback ) => prev instanceof Promise ? prev.then( callback ) : callback();
if ( !keys.length || ( keys.includes( 'length') && this.graph.type === 'ForOfStatement' ) ) {
for ( let [ /* iterationId */, iterationInstance ] of iterationInstances ) {
prev = after( prev, () => iterationInstance.call() );
prev = _await( prev, () => iterationInstance.call() );
}

@@ -92,3 +94,3 @@ } else {

if ( !instance ) continue;
prev = after( prev, () => instance.call() );
prev = _await( prev, () => instance.call() );
}

@@ -129,8 +131,8 @@ }

let prev, entry, refs, after = ( prev, callback ) => prev instanceof Promise ? prev.then( callback ) : callback();
let prev, entry, refs, _await = ( prev, callback ) => prev instanceof Promise ? prev.then( callback ) : callback();
while ( ( entry = thread.sequence.shift() ) && ( refs = [ ...thread.entries.get( entry ) ] ) ) {
prev = after( prev, () => {
prev = _await( prev, () => {
if ( entry.disposed || !entry.filterRefs( refs ).length ) return;
let maybePromise = execute( entry, refs );
after( maybePromise, () => {
_await( maybePromise, () => {
for ( let ref of refs ) {

@@ -146,3 +148,3 @@ [].concat( ref.executionPlan.assigneeRef || ref.executionPlan.assigneeRefs || [] ).forEach( assigneeRef => {

return after( prev, () => {
return _await( prev, () => {
let _ret = this.exits.get( 'return' );

@@ -149,0 +151,0 @@ this.exits.clear();

@@ -5,3 +5,3 @@

*/
import { expect } from 'chai';
import * as Acorn from 'acorn';
import Subscript from '../src/index.js';

@@ -12,3 +12,3 @@ import Observer from '../../observer/src/index.js';

let source2 = `
/*
for ( let propertyName in entries ) {

@@ -46,4 +46,11 @@ console.log( \`Current property name is: \${ propertyName }, and its alias name is: '\${ entries[ propertyName ].name }'\` );

}
*/
let c = 2;
let t = function( $x, b = c ) {
return $x * b;
}
return t( 10 );
`;
let subscriptFunction = new Subscript( 'param1', 'param2', 'param3', source2 );

@@ -76,3 +83,3 @@ // -----------

console.log('');
console.log( subscriptFunction.toString() );
console.log( subscriptFunction.subscriptSource );
console.log('');

@@ -83,3 +90,3 @@ console.log('--------------------------------------------------');

let result = subscriptFunction( 'Some param1', 'Some param2', 2 );
console.log( '+++++', result );
console.log( '------->', result );

@@ -86,0 +93,0 @@ setTimeout(() => {

Sorry, the diff of this file is too big to display

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