sygnal 2.1.0 → 2.3.0

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 CHANGED
@@ -24,7 +24,7 @@ Sygnal provides a structured way to create Cycle.js components that accomplishes
24
24
  - Handle all stream plumbing between components
25
25
  - Support arbitrarily complex applications with deep component hierarchies
26
26
  - Reuse the best patterns from popular frameworks like React and Vue while avoiding the pitfalls
27
- - Support pure Javascript, Typescript, and JSX
27
+ - Support pure Javascript, Typescript, and JSX (including fragments)
28
28
  - Provide application state out of the box, and make it easy to use
29
29
  - Use reasonable defaults while providing access to low-level Cycle.js functionality wherever possible
30
30
  - Provide automatic debugging information
@@ -106,7 +106,22 @@ The results will be in the 'dist' folder, and you can serve it locally by runnin
106
106
  npm preview
107
107
  ```
108
108
 
109
- Alternatively, you can use any other bundler of your choice (Webpack, Babel, Rollup, etc.). To use JSX in your components while using alternative bundlers, you will need to install [snabbdom-pragma](https://www.npmjs.com/package/snabbdom-pragma) and configure your bundler to use it for transforming JSX (see [examples here](https://www.npmjs.com/package/snabbdom-pragma#usage "snabbdom-pragma bundler configuration examples")).
109
+ Alternatively, you can use any other bundler of your choice (Webpack, Babel, Rollup, etc.). To use JSX in your components while using alternative bundlers, you will need to configure your bundler to use Sygnal's JSX pragma. This is slightly different for each bundler, but looks generally like:
110
+
111
+ ```javascript
112
+ // this example is for Vite or esbuild, but most bundlers have options similar to this for handling JSX transpiling
113
+ {
114
+ ...,
115
+ esbuild: {
116
+ // add the import for Sygnal's JSX and Fragment handler to the top of each .jsx and .tsx page automatically
117
+ jsxInject: `import { jsx, Fragment } from 'sygnal/jsx'`,
118
+ // tell the transpiler to use Sygnal's 'jsx' funtion to render JSX elements
119
+ jsxFactory: `jsx`,
120
+ // tell the transpiler to use Sygnal's 'Fragment' funtion to render JSX fragments (<>...</>)
121
+ jsxFragment: 'Fragment'
122
+ },
123
+ }
124
+ ```
110
125
 
111
126
 
112
127
  ## Initialization
@@ -26,10 +26,20 @@ function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Sy
26
26
  function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
27
27
 
28
28
  function collection(component, stateLense) {
29
- var combineList = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : ['DOM'];
30
- var globalList = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : ['EVENTS'];
31
- var stateSourceName = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 'STATE';
29
+ var opts = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
30
+ var _opts$combineList = opts.combineList,
31
+ combineList = _opts$combineList === void 0 ? ['DOM'] : _opts$combineList,
32
+ _opts$globalList = opts.globalList,
33
+ globalList = _opts$globalList === void 0 ? ['EVENTS'] : _opts$globalList,
34
+ _opts$stateSourceName = opts.stateSourceName,
35
+ stateSourceName = _opts$stateSourceName === void 0 ? 'STATE' : _opts$stateSourceName,
36
+ _opts$domSourceName = opts.domSourceName,
37
+ domSourceName = _opts$domSourceName === void 0 ? 'DOM' : _opts$domSourceName,
38
+ _opts$container = opts.container,
39
+ container = _opts$container === void 0 ? 'div' : _opts$container,
40
+ containerClass = opts.containerClass;
32
41
  return function (sources) {
42
+ var key = Date.now();
33
43
  var collectionOpts = {
34
44
  item: component,
35
45
  itemKey: function itemKey(state, ind) {
@@ -46,7 +56,28 @@ function collection(component, stateLense) {
46
56
  stream = _ref2[1];
47
57
 
48
58
  if (combineList.includes(name)) {
49
- acc[name] = instances.pickCombine(name);
59
+ var combined = instances.pickCombine(name);
60
+
61
+ if (name === domSourceName && container) {
62
+ acc.DOM = combined.map(function (children) {
63
+ var data = containerClass ? {
64
+ props: {
65
+ className: containerClass
66
+ }
67
+ } : {};
68
+ return {
69
+ sel: container,
70
+ data: data,
71
+ children: children,
72
+ key: key,
73
+ text: undefined,
74
+ elm: undefined
75
+ };
76
+ });
77
+ } else {
78
+ console.warn('Collections without wrapping containers will fail in unpredictable ways when used inside JSX fragments');
79
+ acc[name] = combined;
80
+ }
50
81
  } else {
51
82
  acc[name] = instances.pickMerge(name);
52
83
  }
package/dist/component.js CHANGED
@@ -10,6 +10,8 @@ var _isolate = _interopRequireDefault(require("@cycle/isolate"));
10
10
 
11
11
  var _collection = _interopRequireDefault(require("./collection.js"));
12
12
 
13
+ var _switchable = _interopRequireDefault(require("./switchable.js"));
14
+
13
15
  var _state2 = require("@cycle/state");
14
16
 
15
17
  var _xstream = _interopRequireWildcard(require("xstream"));
@@ -749,24 +751,16 @@ var Component = /*#__PURE__*/function () {
749
751
 
750
752
  var children$ = _xstream["default"].create().startWith(children);
751
753
 
752
- var propState;
754
+ var stateSource;
753
755
  var sink$;
754
756
 
755
757
  if (isCollection) {
756
- var _objectSpread2;
757
-
758
- var stream, field;
758
+ var _objectSpread3;
759
759
 
760
- if (typeof data.props["for"] === 'string') {
761
- field = data.props["for"];
762
- stream = _this8.sources[_this8.stateSourceName].stream;
763
- } else {
764
- field = 'for';
765
- stream = props$;
766
- }
760
+ var field, lense;
767
761
 
768
- propState = new _state2.StateSource(stream.map(function (val) {
769
- var arr = val[field];
762
+ var stateGetter = function stateGetter(state) {
763
+ var arr = state[field];
770
764
 
771
765
  if (!Array.isArray(arr)) {
772
766
  console.warn("Collection of ".concat(data.props.of, " does not have a valid array in the 'for' property: expects either an array or a string of the name of an array property on the state"));
@@ -774,22 +768,76 @@ var Component = /*#__PURE__*/function () {
774
768
  }
775
769
 
776
770
  return arr;
777
- }).remember());
771
+ };
778
772
 
779
- var sources = _objectSpread(_objectSpread({}, _this8.sources), {}, (_objectSpread2 = {}, _defineProperty(_objectSpread2, _this8.stateSourceName, propState), _defineProperty(_objectSpread2, "props$", props$), _defineProperty(_objectSpread2, "children$", children$), _objectSpread2));
773
+ if (typeof props["for"] === 'string') {
774
+ field = props["for"];
775
+ stateSource = _this8.sources[_this8.stateSourceName];
776
+ lense = {
777
+ get: stateGetter,
778
+ set: function set(state, arr) {
779
+ return _objectSpread(_objectSpread({}, state), {}, _defineProperty({}, field, arr));
780
+ }
781
+ };
782
+ } else {
783
+ field = 'for';
784
+ stateSource = new _state2.StateSource(props$.remember());
785
+ lense = {
786
+ get: stateGetter,
787
+ set: function set(state, arr) {
788
+ return state;
789
+ }
790
+ };
791
+ }
792
+
793
+ var sources = _objectSpread(_objectSpread({}, _this8.sources), {}, (_objectSpread3 = {}, _defineProperty(_objectSpread3, _this8.stateSourceName, stateSource), _defineProperty(_objectSpread3, "props$", props$), _defineProperty(_objectSpread3, "children$", children$), _objectSpread3));
794
+
795
+ var _factory = typeof data.props.of === 'function' ? data.props.of : _this8.components[data.props.of];
780
796
 
781
- var _factory = _this8.components[data.props.of];
782
- var lense = {
783
- get: function get(state) {
784
- return state;
785
- },
786
- set: function set(state) {
787
- return state;
788
- }
789
- };
790
797
  sink$ = (0, _collection["default"])(_factory, lense)(sources);
791
- } else if (isSwitchable) {} else {
792
- var _objectSpread3;
798
+
799
+ if (_typeof(sink$) !== 'object') {
800
+ throw new Error('Invalid sinks returned from component factory of collection element');
801
+ }
802
+ } else if (isSwitchable) {
803
+ var _objectSpread4;
804
+
805
+ var stateField = data.props.state;
806
+
807
+ if (typeof stateField === 'string') {
808
+ var stream = _this8.sources[_this8.stateSourceName].stream;
809
+ stateSource = new _state2.StateSource(stream.map(function (val) {
810
+ if (_typeof(val) !== 'object') {
811
+ console.error("Switchable Error: Invalid or undefined state");
812
+ return;
813
+ }
814
+
815
+ var newVal = val[stateField];
816
+
817
+ if (typeof newVal === 'undefined') {
818
+ console.warn("Specified state field '".concat(stateField, "' for switchable element not found"));
819
+ return;
820
+ }
821
+
822
+ return newVal;
823
+ }));
824
+ } else {
825
+ stateSource = _this8.sources[_this8.stateSourceName];
826
+ }
827
+
828
+ var switchableComponents = data.props.of;
829
+
830
+ var _sources = _objectSpread(_objectSpread({}, _this8.sources), {}, (_objectSpread4 = {}, _defineProperty(_objectSpread4, _this8.stateSourceName, stateSource), _defineProperty(_objectSpread4, "props$", props$), _defineProperty(_objectSpread4, "children$", children$), _objectSpread4));
831
+
832
+ sink$ = (0, _switchable["default"])(switchableComponents, props$.map(function (props) {
833
+ return props.current;
834
+ }))(_sources);
835
+
836
+ if (_typeof(sink$) !== 'object') {
837
+ throw new Error('Invalid sinks returned from component factory of switchable element');
838
+ }
839
+ } else {
840
+ var _objectSpread5;
793
841
 
794
842
  var _lense = function _lense(props) {
795
843
  var state = props.state;
@@ -802,15 +850,21 @@ var Component = /*#__PURE__*/function () {
802
850
  return _objectSpread(_objectSpread({}, copy), state);
803
851
  };
804
852
 
805
- propState = new _state2.StateSource(props$.map(_lense));
853
+ stateSource = new _state2.StateSource(props$.map(_lense));
806
854
 
807
- var _sources = _objectSpread(_objectSpread({}, _this8.sources), {}, (_objectSpread3 = {}, _defineProperty(_objectSpread3, _this8.stateSourceName, propState), _defineProperty(_objectSpread3, "props$", props$), _defineProperty(_objectSpread3, "children$", children$), _objectSpread3));
855
+ var _sources2 = _objectSpread(_objectSpread({}, _this8.sources), {}, (_objectSpread5 = {}, _defineProperty(_objectSpread5, _this8.stateSourceName, stateSource), _defineProperty(_objectSpread5, "props$", props$), _defineProperty(_objectSpread5, "children$", children$), _objectSpread5));
808
856
 
809
- sink$ = factory(_sources);
857
+ sink$ = factory(_sources2);
858
+
859
+ if (_typeof(sink$) !== 'object') {
860
+ var name = componentName === 'sygnal-factory' ? 'custom element' : componentName;
861
+ throw new Error('Invalid sinks returned from component factory:', name);
862
+ }
810
863
  }
811
864
 
812
- var originalDOMSink = sink$[_this8.DOMSourceName];
813
- sink$[_this8.DOMSourceName] = propState.stream.map(function (state) {
865
+ var originalDOMSink = sink$[_this8.DOMSourceName].remember();
866
+
867
+ sink$[_this8.DOMSourceName] = stateSource.stream.map(function (state) {
814
868
  return originalDOMSink.compose((0, _debounce["default"])(10));
815
869
  }).flatten();
816
870
  acc[id] = {
@@ -1080,8 +1134,9 @@ function getComponents(currentElement, componentNames) {
1080
1134
  var sel = currentElement.sel;
1081
1135
  var isCollection = sel && sel.toLowerCase() === 'collection';
1082
1136
  var isSwitchable = sel && sel.toLowerCase() === 'switchable';
1083
- var isComponent = sel && ['collection', 'swtichable', 'sygnal-factory'].concat(_toConsumableArray(componentNames)).includes(currentElement.sel) || typeof ((_currentElement$data2 = currentElement.data) === null || _currentElement$data2 === void 0 ? void 0 : (_currentElement$data3 = _currentElement$data2.props) === null || _currentElement$data3 === void 0 ? void 0 : _currentElement$data3.sygnalFactory) === 'function';
1137
+ var isComponent = sel && ['collection', 'switchable', 'sygnal-factory'].concat(_toConsumableArray(componentNames)).includes(currentElement.sel) || typeof ((_currentElement$data2 = currentElement.data) === null || _currentElement$data2 === void 0 ? void 0 : (_currentElement$data3 = _currentElement$data2.props) === null || _currentElement$data3 === void 0 ? void 0 : _currentElement$data3.sygnalFactory) === 'function';
1084
1138
  var props = currentElement.data && currentElement.data.props || {};
1139
+ var attrs = currentElement.data && currentElement.data.attrs || {};
1085
1140
  var children = currentElement.children || [];
1086
1141
  var found = {};
1087
1142
 
@@ -1089,25 +1144,27 @@ function getComponents(currentElement, componentNames) {
1089
1144
  var id = getComponentIdFromElement(currentElement);
1090
1145
 
1091
1146
  if (isCollection) {
1147
+ var _currentElement$data4;
1148
+
1092
1149
  if (!props.of) throw new Error("Collection element missing required 'component' property");
1093
- if (typeof props.of !== 'string') throw new Error("Invalid 'component' property of collection element: found ".concat(_typeof(props.of), " requires string"));
1094
- if (!componentNames.includes(props.of)) throw new Error("Specified component for collection not found: ".concat(props.of));
1095
- if (!props["for"] || !(typeof props["for"] === 'string' || Array.isArray(props["for"]))) console.warn("No valid array found in the 'value' property of collection ".concat(props.of, ": no collection components will be created"));
1150
+ if (typeof props.of !== 'string' && typeof props.of !== 'function') throw new Error("Invalid 'component' property of collection element: found ".concat(_typeof(props.of), " requires string or component factory function"));
1151
+ if (typeof props.of !== 'function' && !componentNames.includes(props.of)) throw new Error("Specified component for collection not found: ".concat(props.of));
1152
+ if (!attrs["for"] || !(typeof attrs["for"] === 'string' || Array.isArray(attrs["for"]))) console.warn("No valid array found in the 'value' property of collection ".concat(props.of, ": no collection components will be created"));
1096
1153
  currentElement.data.isCollection = true;
1097
- currentElement.data.component = props.component; // currentElement.data.componentArray = props.value
1154
+ (_currentElement$data4 = currentElement.data).props || (_currentElement$data4.props = {});
1155
+ currentElement.data.props["for"] = attrs["for"];
1156
+ currentElement.data.attrs = undefined;
1098
1157
  } else if (isSwitchable) {
1099
- if (!props.components) throw new Error("Switchable element missing required 'components' property");
1100
- if (_typeof(props.components) !== 'object') throw new Error("Invalid 'components' property of switchable element: found ".concat(_typeof(props.components), " requires object mapping names to component factories"));
1101
- var switchableComponents = Object.values(props.components);
1158
+ if (!props.of) throw new Error("Switchable element missing required 'of' property");
1159
+ if (_typeof(props.of) !== 'object') throw new Error("Invalid 'components' property of switchable element: found ".concat(_typeof(props.of), " requires object mapping names to component factories"));
1160
+ var switchableComponents = Object.values(props.of);
1102
1161
  if (!switchableComponents.every(function (comp) {
1103
1162
  return typeof comp === 'function';
1104
- })) throw new Error("One or more invalid component factories for switchable element is not a valid component factory");
1105
- if (!props.current || typeof props.current !== 'string') throw new Error("Missing or invalid 'current' property for switchable element: found ".concat(_typeof(props.current), " requires string"));
1106
- var switchableComponentNames = Object.keys(props.components);
1163
+ })) throw new Error("One or more components provided to switchable element is not a valid component factory");
1164
+ if (!props.current || typeof props.current !== 'string' && typeof props.current !== 'function') throw new Error("Missing or invalid 'current' property for switchable element: found '".concat(_typeof(props.current), "' requires string or function"));
1165
+ var switchableComponentNames = Object.keys(props.of);
1107
1166
  if (!switchableComponentNames.includes(props.current)) throw new Error("Component '".concat(props.current, "' not found in switchable element"));
1108
1167
  currentElement.data.isSwitchable = true;
1109
- currentElement.data.components = props.components;
1110
- currentElement.data.currentComponent = props.current;
1111
1168
  } else {}
1112
1169
 
1113
1170
  found[id] = currentElement;
@@ -1131,16 +1188,16 @@ function getComponents(currentElement, componentNames) {
1131
1188
  }
1132
1189
 
1133
1190
  function injectComponents(currentElement, components, componentNames) {
1134
- var _currentElement$data4, _currentElement$data5, _currentElement$data6, _currentElement$data7, _currentElement$data8;
1191
+ var _currentElement$data5, _currentElement$data6, _currentElement$data7, _currentElement$data8, _currentElement$data9;
1135
1192
 
1136
1193
  var isNestedElement = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
1137
1194
  if (!currentElement) return;
1138
- if ((_currentElement$data4 = currentElement.data) !== null && _currentElement$data4 !== void 0 && _currentElement$data4.componentsInjected) return currentElement;
1195
+ if ((_currentElement$data5 = currentElement.data) !== null && _currentElement$data5 !== void 0 && _currentElement$data5.componentsInjected) return currentElement;
1139
1196
  if (!isNestedElement && currentElement.data) currentElement.data.componentsInjected = true;
1140
1197
  var sel = currentElement.sel || 'NO SELECTOR';
1141
- var isComponent = ['collection', 'swtichable', 'sygnal-factory'].concat(_toConsumableArray(componentNames)).includes(sel) || typeof ((_currentElement$data5 = currentElement.data) === null || _currentElement$data5 === void 0 ? void 0 : (_currentElement$data6 = _currentElement$data5.props) === null || _currentElement$data6 === void 0 ? void 0 : _currentElement$data6.sygnalFactory) === 'function';
1142
- var isCollection = currentElement === null || currentElement === void 0 ? void 0 : (_currentElement$data7 = currentElement.data) === null || _currentElement$data7 === void 0 ? void 0 : _currentElement$data7.isCollection;
1143
- var isSwitchable = currentElement === null || currentElement === void 0 ? void 0 : (_currentElement$data8 = currentElement.data) === null || _currentElement$data8 === void 0 ? void 0 : _currentElement$data8.isSwitchable;
1198
+ var isComponent = ['collection', 'switchable', 'sygnal-factory'].concat(_toConsumableArray(componentNames)).includes(sel) || typeof ((_currentElement$data6 = currentElement.data) === null || _currentElement$data6 === void 0 ? void 0 : (_currentElement$data7 = _currentElement$data6.props) === null || _currentElement$data7 === void 0 ? void 0 : _currentElement$data7.sygnalFactory) === 'function';
1199
+ var isCollection = currentElement === null || currentElement === void 0 ? void 0 : (_currentElement$data8 = currentElement.data) === null || _currentElement$data8 === void 0 ? void 0 : _currentElement$data8.isCollection;
1200
+ var isSwitchable = currentElement === null || currentElement === void 0 ? void 0 : (_currentElement$data9 = currentElement.data) === null || _currentElement$data9 === void 0 ? void 0 : _currentElement$data9.isSwitchable;
1144
1201
  var props = currentElement.data && currentElement.data.props || {};
1145
1202
  var children = currentElement.children || [];
1146
1203
 
@@ -1151,8 +1208,10 @@ function injectComponents(currentElement, components, componentNames) {
1151
1208
  if (isCollection) {
1152
1209
  currentElement.sel = 'div';
1153
1210
  delete currentElement.elm;
1154
- currentElement.children = _component;
1211
+ currentElement.children = Array.isArray(_component) ? _component : [_component];
1155
1212
  return currentElement;
1213
+ } else if (isSwitchable) {
1214
+ return _component;
1156
1215
  } else {
1157
1216
  return _component;
1158
1217
  }
@@ -45,7 +45,7 @@ var considerSvg = function considerSvg(vnode) {
45
45
  };
46
46
 
47
47
  var rewrites = {
48
- // for: 'attrs',
48
+ "for": 'attrs',
49
49
  role: 'attrs',
50
50
  tabindex: 'attrs',
51
51
  'aria-*': 'attrs',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sygnal",
3
- "version": "2.1.0",
3
+ "version": "2.3.0",
4
4
  "description": "An intuitive framework for building fast and small components or applications based on Cycle.js",
5
5
  "main": "./dist/index.js",
6
6
  "exports": {
package/sygnal-1.2.1.tgz DELETED
Binary file
package/sygnal-2.0.0.tgz DELETED
Binary file
package/sygnal-2.0.1.tgz DELETED
Binary file