sygnal 5.3.3 → 5.3.5

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.
@@ -4362,12 +4362,41 @@ const styleModule = {
4362
4362
  remove: applyRemoveStyle,
4363
4363
  };
4364
4364
 
4365
+ /**
4366
+ * Snabbdom module that fixes <select> value assignment.
4367
+ *
4368
+ * Problem: snabbdom's createElm() fires the propsModule create hook
4369
+ * (which sets elm.value) BEFORE appending child <option> elements.
4370
+ * The browser silently ignores the value assignment because no matching
4371
+ * option exists yet, so <select> always shows the first option.
4372
+ *
4373
+ * Fix: collect <select> elements that have a value prop during create,
4374
+ * then re-apply the value in the post hook (after all elements and
4375
+ * children have been inserted).
4376
+ */
4377
+ let pendingSelects = [];
4378
+ function createSelect(_oldVnode, vnode) {
4379
+ const elm = vnode.elm;
4380
+ if (elm && elm.tagName === 'SELECT' && vnode.data?.props?.value !== undefined) {
4381
+ pendingSelects.push({ elm: elm, value: vnode.data.props.value });
4382
+ }
4383
+ }
4384
+ function postPatch() {
4385
+ for (let i = 0; i < pendingSelects.length; i++) {
4386
+ const { elm, value } = pendingSelects[i];
4387
+ elm.value = value;
4388
+ }
4389
+ pendingSelects = [];
4390
+ }
4391
+ const selectModule = { create: createSelect, post: postPatch };
4392
+
4365
4393
  const modules = [
4366
4394
  styleModule,
4367
4395
  class_js.classModule,
4368
4396
  props_js.propsModule,
4369
4397
  attributes_js.attributesModule,
4370
4398
  dataset_js.datasetModule,
4399
+ selectModule,
4371
4400
  ];
4372
4401
 
4373
4402
  class SymbolTree {
@@ -4360,12 +4360,41 @@ const styleModule = {
4360
4360
  remove: applyRemoveStyle,
4361
4361
  };
4362
4362
 
4363
+ /**
4364
+ * Snabbdom module that fixes <select> value assignment.
4365
+ *
4366
+ * Problem: snabbdom's createElm() fires the propsModule create hook
4367
+ * (which sets elm.value) BEFORE appending child <option> elements.
4368
+ * The browser silently ignores the value assignment because no matching
4369
+ * option exists yet, so <select> always shows the first option.
4370
+ *
4371
+ * Fix: collect <select> elements that have a value prop during create,
4372
+ * then re-apply the value in the post hook (after all elements and
4373
+ * children have been inserted).
4374
+ */
4375
+ let pendingSelects = [];
4376
+ function createSelect(_oldVnode, vnode) {
4377
+ const elm = vnode.elm;
4378
+ if (elm && elm.tagName === 'SELECT' && vnode.data?.props?.value !== undefined) {
4379
+ pendingSelects.push({ elm: elm, value: vnode.data.props.value });
4380
+ }
4381
+ }
4382
+ function postPatch() {
4383
+ for (let i = 0; i < pendingSelects.length; i++) {
4384
+ const { elm, value } = pendingSelects[i];
4385
+ elm.value = value;
4386
+ }
4387
+ pendingSelects = [];
4388
+ }
4389
+ const selectModule = { create: createSelect, post: postPatch };
4390
+
4363
4391
  const modules = [
4364
4392
  styleModule,
4365
4393
  classModule,
4366
4394
  propsModule,
4367
4395
  attributesModule,
4368
4396
  datasetModule,
4397
+ selectModule,
4369
4398
  ];
4370
4399
 
4371
4400
  class SymbolTree {
package/dist/index.cjs.js CHANGED
@@ -1271,12 +1271,41 @@ const styleModule = {
1271
1271
  remove: applyRemoveStyle,
1272
1272
  };
1273
1273
 
1274
+ /**
1275
+ * Snabbdom module that fixes <select> value assignment.
1276
+ *
1277
+ * Problem: snabbdom's createElm() fires the propsModule create hook
1278
+ * (which sets elm.value) BEFORE appending child <option> elements.
1279
+ * The browser silently ignores the value assignment because no matching
1280
+ * option exists yet, so <select> always shows the first option.
1281
+ *
1282
+ * Fix: collect <select> elements that have a value prop during create,
1283
+ * then re-apply the value in the post hook (after all elements and
1284
+ * children have been inserted).
1285
+ */
1286
+ let pendingSelects = [];
1287
+ function createSelect(_oldVnode, vnode) {
1288
+ const elm = vnode.elm;
1289
+ if (elm && elm.tagName === 'SELECT' && vnode.data?.props?.value !== undefined) {
1290
+ pendingSelects.push({ elm: elm, value: vnode.data.props.value });
1291
+ }
1292
+ }
1293
+ function postPatch() {
1294
+ for (let i = 0; i < pendingSelects.length; i++) {
1295
+ const { elm, value } = pendingSelects[i];
1296
+ elm.value = value;
1297
+ }
1298
+ pendingSelects = [];
1299
+ }
1300
+ const selectModule = { create: createSelect, post: postPatch };
1301
+
1274
1302
  const modules = [
1275
1303
  styleModule,
1276
1304
  class_js.classModule,
1277
1305
  props_js.propsModule,
1278
1306
  attributes_js.attributesModule,
1279
1307
  dataset_js.datasetModule,
1308
+ selectModule,
1280
1309
  ];
1281
1310
 
1282
1311
  class SymbolTree {
package/dist/index.d.ts CHANGED
@@ -42,11 +42,13 @@ type NextFunction<ACTIONS = any> = ACTIONS extends object
42
42
  ) => void
43
43
  : (action: string, data?: any, delay?: number) => void
44
44
 
45
- type Reducer<STATE, PROPS, ACTIONS = any, DATA = any, RETURN = any> = (
45
+ type ReducerExtras<PROPS, CONTEXT> = PROPS & { context: CONTEXT; children?: JSX.Element | JSX.Element[]; slots?: Record<string, JSX.Element[]> }
46
+
47
+ type Reducer<STATE, PROPS, ACTIONS = any, DATA = any, RETURN = any, CONTEXT = {}> = (
46
48
  state: STATE,
47
49
  args: DATA,
48
50
  next: NextFunction<ACTIONS>,
49
- props: PROPS
51
+ props: ReducerExtras<PROPS, CONTEXT>
50
52
  ) => RETURN | ABORT | undefined
51
53
 
52
54
  export type ExactShape<EXPECTED, ACTUAL extends EXPECTED> = ACTUAL &
@@ -76,24 +78,24 @@ type ResolvedNonStateSinkReturns<SINK_RETURNS extends NonStateSinkReturns = {}>
76
78
  * - true: Whatever value is received from the intent for this action is passed on as-is.
77
79
  * - Function: A reducer
78
80
  */
79
- type SinkValue<STATE, PROPS, ACTIONS, DATA, RETURN, CALCULATED> =
81
+ type SinkValue<STATE, PROPS, ACTIONS, DATA, RETURN, CALCULATED, CONTEXT = {}> =
80
82
  | true
81
- | Reducer<STATE & CALCULATED, PROPS, ACTIONS, DATA, RETURN>
83
+ | Reducer<STATE & CALCULATED, PROPS, ACTIONS, DATA, RETURN, CONTEXT>
82
84
 
83
- type EffectReducer<STATE, PROPS, ACTIONS, DATA, CALCULATED> =
84
- | ((state: STATE & CALCULATED, args: DATA, next: NextFunction<ACTIONS>, props: PROPS) => void)
85
+ type EffectReducer<STATE, PROPS, ACTIONS, DATA, CALCULATED, CONTEXT = {}> =
86
+ | ((state: STATE & CALCULATED, args: DATA, next: NextFunction<ACTIONS>, props: ReducerExtras<PROPS, CONTEXT>) => void)
85
87
 
86
- type DefaultSinks<STATE, PROPS, ACTIONS, DATA, CALCULATED, SINK_RETURNS extends NonStateSinkReturns = {}> = {
87
- STATE?: SinkValue<STATE, PROPS, ACTIONS, DATA, STATE, CALCULATED>;
88
- EVENTS?: SinkValue<STATE, PROPS, ACTIONS, DATA, ResolvedNonStateSinkReturns<SINK_RETURNS>['EVENTS'], CALCULATED>;
89
- LOG?: SinkValue<STATE, PROPS, ACTIONS, DATA, ResolvedNonStateSinkReturns<SINK_RETURNS>['LOG'], CALCULATED>;
90
- PARENT?: SinkValue<STATE, PROPS, ACTIONS, DATA, ResolvedNonStateSinkReturns<SINK_RETURNS>['PARENT'], CALCULATED>;
91
- EFFECT?: EffectReducer<STATE, PROPS, ACTIONS, DATA, CALCULATED>;
88
+ type DefaultSinks<STATE, PROPS, ACTIONS, DATA, CALCULATED, SINK_RETURNS extends NonStateSinkReturns = {}, CONTEXT = {}> = {
89
+ STATE?: SinkValue<STATE, PROPS, ACTIONS, DATA, STATE, CALCULATED, CONTEXT>;
90
+ EVENTS?: SinkValue<STATE, PROPS, ACTIONS, DATA, ResolvedNonStateSinkReturns<SINK_RETURNS>['EVENTS'], CALCULATED, CONTEXT>;
91
+ LOG?: SinkValue<STATE, PROPS, ACTIONS, DATA, ResolvedNonStateSinkReturns<SINK_RETURNS>['LOG'], CALCULATED, CONTEXT>;
92
+ PARENT?: SinkValue<STATE, PROPS, ACTIONS, DATA, ResolvedNonStateSinkReturns<SINK_RETURNS>['PARENT'], CALCULATED, CONTEXT>;
93
+ EFFECT?: EffectReducer<STATE, PROPS, ACTIONS, DATA, CALCULATED, CONTEXT>;
92
94
  }
93
95
 
94
- type CustomDriverSinks<STATE, PROPS, DRIVERS, ACTIONS, ACTION_ENTRY, CALCULATED> = keyof DRIVERS extends never
96
+ type CustomDriverSinks<STATE, PROPS, DRIVERS, ACTIONS, ACTION_ENTRY, CALCULATED, CONTEXT = {}> = keyof DRIVERS extends never
95
97
  ? {
96
- [driver: string]: SinkValue<STATE, PROPS, ACTIONS, any, any, CALCULATED>
98
+ [driver: string]: SinkValue<STATE, PROPS, ACTIONS, any, any, CALCULATED, CONTEXT>
97
99
  }
98
100
  : {
99
101
  [DRIVER_KEY in keyof DRIVERS]: SinkValue<
@@ -102,15 +104,16 @@ type CustomDriverSinks<STATE, PROPS, DRIVERS, ACTIONS, ACTION_ENTRY, CALCULATED>
102
104
  ACTIONS,
103
105
  ACTION_ENTRY,
104
106
  DRIVERS[DRIVER_KEY] extends { source: any; sink: any } ? DRIVERS[DRIVER_KEY]['sink'] : any,
105
- CALCULATED
107
+ CALCULATED,
108
+ CONTEXT
106
109
  >
107
110
  }
108
111
 
109
- type ModelEntry<STATE, PROPS, DRIVERS, ACTIONS, ACTION_ENTRY, CALCULATED, SINK_RETURNS extends NonStateSinkReturns = {}> =
110
- | SinkValue<STATE, PROPS, ACTIONS, ACTION_ENTRY, STATE, CALCULATED>
112
+ type ModelEntry<STATE, PROPS, DRIVERS, ACTIONS, ACTION_ENTRY, CALCULATED, SINK_RETURNS extends NonStateSinkReturns = {}, CONTEXT = {}> =
113
+ | SinkValue<STATE, PROPS, ACTIONS, ACTION_ENTRY, STATE, CALCULATED, CONTEXT>
111
114
  | Partial<
112
- DefaultSinks<STATE, PROPS, ACTIONS, ACTION_ENTRY, CALCULATED, SINK_RETURNS> &
113
- CustomDriverSinks<STATE, PROPS, DRIVERS, ACTIONS, ACTION_ENTRY, CALCULATED>
115
+ DefaultSinks<STATE, PROPS, ACTIONS, ACTION_ENTRY, CALCULATED, SINK_RETURNS, CONTEXT> &
116
+ CustomDriverSinks<STATE, PROPS, DRIVERS, ACTIONS, ACTION_ENTRY, CALCULATED, CONTEXT>
114
117
  >
115
118
 
116
119
  type WithDefaultActions<STATE, ACTIONS> = ACTIONS & {
@@ -120,7 +123,7 @@ type WithDefaultActions<STATE, ACTIONS> = ACTIONS & {
120
123
  DISPOSE?: never;
121
124
  }
122
125
 
123
- type ComponentModel<STATE, PROPS, DRIVERS, ACTIONS, CALCULATED, SINK_RETURNS extends NonStateSinkReturns = {}> = keyof ACTIONS extends never
126
+ type ComponentModel<STATE, PROPS, DRIVERS, ACTIONS, CALCULATED, SINK_RETURNS extends NonStateSinkReturns = {}, CONTEXT = {}> = keyof ACTIONS extends never
124
127
  ? {
125
128
  [action: string]: ModelEntry<
126
129
  STATE,
@@ -129,7 +132,8 @@ type ComponentModel<STATE, PROPS, DRIVERS, ACTIONS, CALCULATED, SINK_RETURNS ext
129
132
  WithDefaultActions<STATE, { [action: string]: any }>,
130
133
  any,
131
134
  CALCULATED,
132
- SINK_RETURNS
135
+ SINK_RETURNS,
136
+ CONTEXT
133
137
  >
134
138
  }
135
139
  : {
@@ -140,7 +144,8 @@ type ComponentModel<STATE, PROPS, DRIVERS, ACTIONS, CALCULATED, SINK_RETURNS ext
140
144
  WithDefaultActions<STATE, ACTIONS>,
141
145
  WithDefaultActions<STATE, ACTIONS>[ACTION_KEY],
142
146
  CALCULATED,
143
- SINK_RETURNS
147
+ SINK_RETURNS,
148
+ CONTEXT
144
149
  >
145
150
  }
146
151
 
@@ -259,7 +264,7 @@ export type Component<
259
264
  DOMSourceName?: string;
260
265
  stateSourceName?: string;
261
266
  requestSourceName?: string;
262
- model?: ComponentModel<STATE, PROPS, FixDrivers<DRIVERS>, ACTIONS, CALCULATED, SINK_RETURNS>;
267
+ model?: ComponentModel<STATE, PROPS, FixDrivers<DRIVERS>, ACTIONS, CALCULATED, SINK_RETURNS, CONTEXT>;
263
268
  intent?: ComponentIntent<STATE & CALCULATED, FixDrivers<DRIVERS>, ACTIONS>;
264
269
  initialState?: STATE;
265
270
  calculated?: Calculated<STATE, CALCULATED>;
package/dist/index.esm.js CHANGED
@@ -1254,12 +1254,41 @@ const styleModule = {
1254
1254
  remove: applyRemoveStyle,
1255
1255
  };
1256
1256
 
1257
+ /**
1258
+ * Snabbdom module that fixes <select> value assignment.
1259
+ *
1260
+ * Problem: snabbdom's createElm() fires the propsModule create hook
1261
+ * (which sets elm.value) BEFORE appending child <option> elements.
1262
+ * The browser silently ignores the value assignment because no matching
1263
+ * option exists yet, so <select> always shows the first option.
1264
+ *
1265
+ * Fix: collect <select> elements that have a value prop during create,
1266
+ * then re-apply the value in the post hook (after all elements and
1267
+ * children have been inserted).
1268
+ */
1269
+ let pendingSelects = [];
1270
+ function createSelect(_oldVnode, vnode) {
1271
+ const elm = vnode.elm;
1272
+ if (elm && elm.tagName === 'SELECT' && vnode.data?.props?.value !== undefined) {
1273
+ pendingSelects.push({ elm: elm, value: vnode.data.props.value });
1274
+ }
1275
+ }
1276
+ function postPatch() {
1277
+ for (let i = 0; i < pendingSelects.length; i++) {
1278
+ const { elm, value } = pendingSelects[i];
1279
+ elm.value = value;
1280
+ }
1281
+ pendingSelects = [];
1282
+ }
1283
+ const selectModule = { create: createSelect, post: postPatch };
1284
+
1257
1285
  const modules = [
1258
1286
  styleModule,
1259
1287
  classModule,
1260
1288
  propsModule,
1261
1289
  attributesModule,
1262
1290
  datasetModule,
1291
+ selectModule,
1263
1292
  ];
1264
1293
 
1265
1294
  class SymbolTree {