@reventlessdev/trait-attachments 1.0.0-alpha.4 → 1.0.0-alpha.41

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.
@@ -8,11 +8,12 @@ import * as Attachments_Rules$TraitAttachments from "./Attachments_Rules.res.mjs
8
8
  let configSchema = Sury.$schema(s => ({
9
9
  entity: s.m(Sury.string),
10
10
  entityId: s.m(Sury.string),
11
+ entityIdType: s.m(Sury.$option(Sury.string)),
11
12
  noun: s.m(Sury.string),
12
13
  file: s.m(Sury.string),
13
14
  cardinality: s.m(Sury.$option(Attachments_Rules$TraitAttachments.cardinalitySchema)),
14
15
  created: s.m(Sury.string),
15
- createdCarriesEntityId: s.m(Sury.$option(Sury.bool)),
16
+ createdCarriesEntityId: s.m(Sury.$option(Sury.boolean)),
16
17
  view: s.m(Sury.string),
17
18
  lifecycleType: s.m(Sury.$option(Sury.string)),
18
19
  refType: s.m(Sury.$option(Sury.string)),
@@ -43,6 +44,7 @@ function namesOf(c) {
43
44
  attached: subject + "Attached",
44
45
  removed: subject + "Removed",
45
46
  primarySet: c.entity + "Primary" + c.noun + "Set",
47
+ effectiveChanged: c.entity + "Effective" + c.noun + "Changed",
46
48
  altTextSet: subject + "AltTextSet",
47
49
  notFound: c.entity + "NotFound",
48
50
  notAttached: subject + "NotAttached"
@@ -53,6 +55,19 @@ function refTypeOf(c) {
53
55
  return Stdlib_Option.getOr(c.refType, "Reventless.UploadableImage.t");
54
56
  }
55
57
 
58
+ function idTypeOf(c) {
59
+ return Stdlib_Option.mapOr(c.entityIdType, "string", t => t + ".t");
60
+ }
61
+
62
+ function idValueOf(c, literal) {
63
+ let t = c.entityIdType;
64
+ if (t !== undefined) {
65
+ return t + `.make("` + literal + `")`;
66
+ } else {
67
+ return `"` + literal + `"`;
68
+ }
69
+ }
70
+
56
71
  function viewTypeOf(c) {
57
72
  if (Stdlib_Option.getOr(c.refType, "Reventless.UploadableImage.t").includes("Image")) {
58
73
  return "Reventless.CaptionedImage.t";
@@ -155,7 +170,7 @@ function sliceSpec(c) {
155
170
  let sel = selectionTypeOf(c);
156
171
  let single = Stdlib_Option.getOr(c.cardinality, "Many") === "Single";
157
172
  let attrs = commandAttributes(c);
158
- let createdArm = Stdlib_Option.getOr(c.createdCarriesEntityId, true) ? ` | ` + c.created + `({ ` + c.entityId + `: string})` : ` | ` + c.created;
173
+ let createdArm = Stdlib_Option.getOr(c.createdCarriesEntityId, true) ? ` | ` + c.created + `({ ` + c.entityId + `: ` + idTypeOf(c) + `})` : ` | ` + c.created;
159
174
  let primaryArm = prefix => {
160
175
  if (single) {
161
176
  return [];
@@ -189,6 +204,7 @@ function sliceSpec(c) {
189
204
  primaryArm(""),
190
205
  [
191
206
  ` | ` + n.altTextSet + `({ ` + c.file + `: ` + ref + `, altText: string})`,
207
+ ` | ` + n.effectiveChanged + `({ ` + c.file + `?: ` + ref + `})`,
192
208
  ` // TODO(graft): add the events this host's own refusal turns on — whatever`,
193
209
  ` // moves it into a state where attachments may not be changed.`,
194
210
  ``
@@ -214,12 +230,12 @@ function sliceSpec(c) {
214
230
  [
215
231
  `@schema`,
216
232
  `type command =`,
217
- attrs + n.attachCmd + `({ ` + c.entityId + `: string, ` + c.file + `: ` + ref + `, altText?: string})`,
218
- single ? attrs + n.removeCmd + `({ ` + c.entityId + `: string})` : attrs + n.removeCmd + `({ ` + c.entityId + `: string, ` + c.file + `: ` + sel + `})`
233
+ attrs + n.attachCmd + `({ ` + c.entityId + `: ` + idTypeOf(c) + `, ` + c.file + `: ` + ref + `, altText?: string})`,
234
+ single ? attrs + n.removeCmd + `({ ` + c.entityId + `: ` + idTypeOf(c) + `})` : attrs + n.removeCmd + `({ ` + c.entityId + `: ` + idTypeOf(c) + `, ` + c.file + `: ` + sel + `})`
219
235
  ],
220
- single ? [] : [attrs + n.setPrimaryCmd + `({ ` + c.entityId + `: string, ` + c.file + `: ` + sel + `})`],
236
+ single ? [] : [attrs + n.setPrimaryCmd + `({ ` + c.entityId + `: ` + idTypeOf(c) + `, ` + c.file + `: ` + sel + `})`],
221
237
  [
222
- single ? attrs + n.setAltTextCmd + `({ ` + c.entityId + `: string, altText: string})` : attrs + n.setAltTextCmd + `({ ` + c.entityId + `: string, ` + c.file + `: ` + sel + `, altText: string})`,
238
+ single ? attrs + n.setAltTextCmd + `({ ` + c.entityId + `: ` + idTypeOf(c) + `, altText: string})` : attrs + n.setAltTextCmd + `({ ` + c.entityId + `: ` + idTypeOf(c) + `, ` + c.file + `: ` + sel + `, altText: string})`,
223
239
  ``,
224
240
  `@schema`,
225
241
  `type error =`,
@@ -229,12 +245,16 @@ function sliceSpec(c) {
229
245
  ``,
230
246
  `@schema`,
231
247
  `type event =`,
232
- ` | ` + n.attached + `({ ` + c.entityId + `: string, ` + c.file + `: ` + ref + `, altText?: string})`,
233
- ` | ` + n.removed + `({ ` + c.entityId + `: string, ` + c.file + `: ` + ref + `})`
248
+ ` | ` + n.attached + `({ ` + c.entityId + `: ` + idTypeOf(c) + `, ` + c.file + `: ` + ref + `, altText?: string})`,
249
+ ` | ` + n.removed + `({ ` + c.entityId + `: ` + idTypeOf(c) + `, ` + c.file + `: ` + ref + `})`
234
250
  ],
235
- primaryArm(c.entityId + `: string, `),
251
+ primaryArm(c.entityId + `: ` + idTypeOf(c) + `, `),
236
252
  [
237
- ` | ` + n.altTextSet + `({ ` + c.entityId + `: string, ` + c.file + `: ` + ref + `, altText: string})`,
253
+ ` | ` + n.altTextSet + `({ ` + c.entityId + `: ` + idTypeOf(c) + `, ` + c.file + `: ` + ref + `, altText: string})`,
254
+ ` // The member a reader should now show, or none. A conclusion rather than a`,
255
+ ` // decision: most of the moves that change it — a first attachment, a removal`,
256
+ ` // promoting the next — are nobody's choice, so nothing else announces them.`,
257
+ ` | ` + n.effectiveChanged + `({ ` + c.entityId + `: ` + idTypeOf(c) + `, ` + c.file + `?: ` + ref + `})`,
238
258
  ``
239
259
  ],
240
260
  commandTransitionBinding(c),
@@ -273,6 +293,7 @@ function sliceBehavior(c) {
273
293
  single ? [] : [` | ` + n.primarySet + `({` + c.file + `}) => fold(PrimarySet({ref: ` + c.file + `}))`],
274
294
  [
275
295
  ` | ` + n.altTextSet + `({` + c.file + `, altText}) => fold(AltTextSet({ref: ` + c.file + `, altText}))`,
296
+ ` | ` + n.effectiveChanged + `({` + c.file + `: ?ref}) => fold(EffectiveChanged({ref: ref}))`,
276
297
  ` // TODO(graft): fold this host's own events into its own state.`,
277
298
  ` }`,
278
299
  `}`,
@@ -332,6 +353,12 @@ function sliceBehavior(c) {
332
353
  ) + n.altTextSet + `({` + c.entityId + `, ` + c.file + `: ref, altText})` + (
333
354
  single ? ")" : ""
334
355
  ),
356
+ ` | Attachments.EffectiveChanged({ref}) =>`,
357
+ ` ` + (
358
+ single ? "Some(" : ""
359
+ ) + n.effectiveChanged + `({` + c.entityId + `, ` + c.file + `: ?ref})` + (
360
+ single ? ")" : ""
361
+ ),
335
362
  ` }`,
336
363
  ``,
337
364
  `let decide = (state, command) =>`,
@@ -358,7 +385,7 @@ function conformanceBinding(c) {
358
385
  let id = "e1";
359
386
  let refA = Stdlib_Option.getOr(c.refA, `/uploads/00000000-0000-4000-8000-000000000001/a`);
360
387
  let refB = Stdlib_Option.getOr(c.refB, `/uploads/00000000-0000-4000-8000-000000000002/b`);
361
- let createdValue = Stdlib_Option.getOr(c.createdCarriesEntityId, true) ? c.created + `({ ` + c.entityId + `: "` + id + `"})` : c.created;
388
+ let createdValue = Stdlib_Option.getOr(c.createdCarriesEntityId, true) ? c.created + `({ ` + c.entityId + `: ` + idValueOf(c, id) + `})` : c.created;
362
389
  return Belt_Array.concatMany([
363
390
  [
364
391
  `// The Attachments trait's conformance suite, bound to \`` + n.slice + `\`.`,
@@ -373,35 +400,43 @@ function conformanceBinding(c) {
373
400
  ` module Behavior = ` + n.slice + `_Behavior`,
374
401
  ``,
375
402
  ` // Annotated: the slice consumes and emits same-named constructors.`,
376
- ` let created: array<` + n.slice + `.consumedEvent> = [` + createdValue + `]`,
377
- ` let attachedC = (ref): ` + n.slice + `.consumedEvent => ` + n.attached + `({ ` + c.file + `: ref})`,
378
- ` let removedC = (ref): ` + n.slice + `.consumedEvent => ` + n.removed + `({ ` + c.file + `: ref})`
403
+ ` // The same facts as the slice consumes them: no ` + c.entityId + `, because the`,
404
+ ` // partition already says which entity they belong to.`,
405
+ ` module Consumed = {`,
406
+ ` let created: array<` + n.slice + `.consumedEvent> = [` + createdValue + `]`,
407
+ ` let attached = (ref): ` + n.slice + `.consumedEvent => ` + n.attached + `({ ` + c.file + `: ref})`,
408
+ ` let removed = (ref): ` + n.slice + `.consumedEvent => ` + n.removed + `({ ` + c.file + `: ref})`
379
409
  ],
380
- single ? [] : [` let primarySetC = (ref): ` + n.slice + `.consumedEvent => ` + n.primarySet + `({ ` + c.file + `: ref})`],
410
+ single ? [] : [` let primarySet = (ref): ` + n.slice + `.consumedEvent => ` + n.primarySet + `({ ` + c.file + `: ref})`],
381
411
  [
382
- ` let altTextSetC = (ref, altText): ` + n.slice + `.consumedEvent =>`,
383
- ` ` + n.altTextSet + `({ ` + c.file + `: ref, altText})`,
412
+ ` let altTextSet = (ref, altText): ` + n.slice + `.consumedEvent =>`,
413
+ ` ` + n.altTextSet + `({ ` + c.file + `: ref, altText})`,
414
+ ` let effectiveChanged = (ref): ` + n.slice + `.consumedEvent =>`,
415
+ ` ` + n.effectiveChanged + `({ ` + c.file + `: ?ref})`,
416
+ ` }`,
384
417
  ``,
385
- ` let attach = ref => ` + n.slice + `.` + n.attachCmd + `({ ` + c.entityId + `: "` + id + `", ` + c.file + `: ref})`
418
+ ` let attach = ref => ` + n.slice + `.` + n.attachCmd + `({ ` + c.entityId + `: ` + idValueOf(c, id) + `, ` + c.file + `: ref})`
386
419
  ],
387
- single ? [` let clear = ` + n.slice + `.` + n.removeCmd + `({ ` + c.entityId + `: "` + id + `"})`] : [
388
- ` let remove = ref => ` + n.slice + `.` + n.removeCmd + `({ ` + c.entityId + `: "` + id + `", ` + c.file + `: ref})`,
420
+ single ? [` let clear = ` + n.slice + `.` + n.removeCmd + `({ ` + c.entityId + `: ` + idValueOf(c, id) + `})`] : [
421
+ ` let remove = ref => ` + n.slice + `.` + n.removeCmd + `({ ` + c.entityId + `: ` + idValueOf(c, id) + `, ` + c.file + `: ref})`,
389
422
  ` let setPrimary = ref =>`,
390
- ` ` + n.slice + `.` + n.setPrimaryCmd + `({ ` + c.entityId + `: "` + id + `", ` + c.file + `: ref})`
423
+ ` ` + n.slice + `.` + n.setPrimaryCmd + `({ ` + c.entityId + `: ` + idValueOf(c, id) + `, ` + c.file + `: ref})`
391
424
  ],
392
425
  [
393
- single ? ` let setAltText = altText => ` + n.slice + `.` + n.setAltTextCmd + `({ ` + c.entityId + `: "` + id + `", altText})` : ` let setAltText = (ref, altText) =>\n ` + n.slice + `.` + n.setAltTextCmd + `({ ` + c.entityId + `: "` + id + `", ` + c.file + `: ref, altText})`,
426
+ single ? ` let setAltText = altText => ` + n.slice + `.` + n.setAltTextCmd + `({ ` + c.entityId + `: ` + idValueOf(c, id) + `, altText})` : ` let setAltText = (ref, altText) =>\n ` + n.slice + `.` + n.setAltTextCmd + `({ ` + c.entityId + `: ` + idValueOf(c, id) + `, ` + c.file + `: ref, altText})`,
394
427
  ``,
395
- ` let attached = ref => ` + n.slice + `.` + n.attached + `({ ` + c.entityId + `: "` + id + `", ` + c.file + `: ref})`,
396
- ` let removed = ref => ` + n.slice + `.` + n.removed + `({ ` + c.entityId + `: "` + id + `", ` + c.file + `: ref})`
428
+ ` let attached = ref => ` + n.slice + `.` + n.attached + `({ ` + c.entityId + `: ` + idValueOf(c, id) + `, ` + c.file + `: ref})`,
429
+ ` let removed = ref => ` + n.slice + `.` + n.removed + `({ ` + c.entityId + `: ` + idValueOf(c, id) + `, ` + c.file + `: ref})`
397
430
  ],
398
431
  single ? [] : [
399
432
  ` let primarySet = ref =>`,
400
- ` ` + n.slice + `.` + n.primarySet + `({ ` + c.entityId + `: "` + id + `", ` + c.file + `: ref})`
433
+ ` ` + n.slice + `.` + n.primarySet + `({ ` + c.entityId + `: ` + idValueOf(c, id) + `, ` + c.file + `: ref})`
401
434
  ],
402
435
  [
403
436
  ` let altTextSet = (ref, altText) =>`,
404
- ` ` + n.slice + `.` + n.altTextSet + `({ ` + c.entityId + `: "` + id + `", ` + c.file + `: ref, altText})`,
437
+ ` ` + n.slice + `.` + n.altTextSet + `({ ` + c.entityId + `: ` + idValueOf(c, id) + `, ` + c.file + `: ref, altText})`,
438
+ ` let effectiveChanged = ref =>`,
439
+ ` ` + n.slice + `.` + n.effectiveChanged + `({ ` + c.entityId + `: ` + idValueOf(c, id) + `, ` + c.file + `: ?ref})`,
405
440
  ` let notAttached = ` + n.slice + `.` + n.notAttached,
406
441
  `}`,
407
442
  ``,
@@ -416,7 +451,7 @@ function conformanceBinding(c) {
416
451
  function singleProjectionPatch(c) {
417
452
  let n = namesOf(c);
418
453
  return {
419
- into: `StateViewSliceStream/` + c.view + `_Projection.res`,
454
+ into: `StateViewStream/` + c.view + `_Projection.res`,
420
455
  at: `the projection's \`switch\`, and one field on \`` + c.view + `\`'s state`,
421
456
  contents: [
422
457
  `// On the view's state, one field — the reference and its text, in one value.`,
@@ -456,7 +491,7 @@ function manyProjectionPatch(c) {
456
491
  let n = namesOf(c);
457
492
  let set = c.file + "s";
458
493
  return {
459
- into: `StateViewSliceStream/` + c.view + `_Projection.res`,
494
+ into: `StateViewStream/` + c.view + `_Projection.res`,
460
495
  at: `the projection's \`switch\`, and one field on \`` + c.view + `\`'s state`,
461
496
  contents: [
462
497
  `// On the view's state, one field — the set, primary first.`,
@@ -525,11 +560,11 @@ function emit(config, into, tests) {
525
560
  return {
526
561
  files: [
527
562
  {
528
- path: into + `/StateChangeSlice/` + n.slice + `.res`,
563
+ path: into + `/StateChange/` + n.slice + `.res`,
529
564
  contents: sliceSpec(config)
530
565
  },
531
566
  {
532
- path: into + `/StateChangeSlice/` + n.slice + `_Behavior.res`,
567
+ path: into + `/StateChange/` + n.slice + `_Behavior.res`,
533
568
  contents: sliceBehavior(config)
534
569
  },
535
570
  {
@@ -547,6 +582,8 @@ export {
547
582
  isSingle,
548
583
  namesOf,
549
584
  refTypeOf,
585
+ idTypeOf,
586
+ idValueOf,
550
587
  viewTypeOf,
551
588
  setFieldOf,
552
589
  selectionBinding,