@manyducks.co/dolla 0.69.2 → 0.69.4

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 @@ States come in two varieties, each with a constructor function and a TypeScript
24
24
  - `.set(value: T)` to replace the stored value.
25
25
  - `.update(callback: (current: T) => T)` which takes a function that receives the current value and returns a new one.
26
26
 
27
- The constructor functions are `$` for `Readable`s and `$$` for `Writable`s. By convention, the names for each are prefixed with the same number of `$`s to indicate its type. This makes the data flow in code a lot easier to understand at a glance.
27
+ The constructor functions are `$` for `Readable` and `$$` for `Writable`. By convention, the names of each are prefixed with `$` or `$$` to indicate its type, making the data flow a lot easier to understand at a glance.
28
28
 
29
29
  ```js
30
30
  import { $, $$ } from "@manyducks.co/dolla";
@@ -131,12 +131,12 @@ Notice that the structure above composes a data pipeline; if any of the data cha
131
131
  The `unwrap` function returns the current value of a Readable or Writable, or if passed a non-Readable value returns that exact value. This function is used to guarantee you have a plain value when you may be dealing with either a container or a plain value.
132
132
 
133
133
  ```js
134
- import { unwrap } from "@manyducks.co/dolla";
134
+ import { $, $$, unwrap } from "@manyducks.co/dolla";
135
135
 
136
136
  const $$number = $$(5);
137
137
 
138
138
  unwrap($$number); // 5
139
- unwrap(State.readable(5)); // 5
139
+ unwrap($(5)); // 5
140
140
  unwrap(5); // 5
141
141
  ```
142
142
 
@@ -398,7 +398,10 @@ Stores are helpful for managing persistent state that needs to be accessed in ma
398
398
  ```js
399
399
  import { App } from "@manyducks.co/dolla";
400
400
 
401
- const app = App();
401
+ const app = App({
402
+ view: LayoutView,
403
+ stores: [MessageStore],
404
+ });
402
405
 
403
406
  // We define a store that just exports a message.
404
407
  function MessageStore() {
@@ -407,9 +410,6 @@ function MessageStore() {
407
410
  };
408
411
  }
409
412
 
410
- // Register it on the app.
411
- app.store(MessageStore);
412
-
413
413
  // All instances of MessageView will share just one instance of MessageStore.
414
414
  function MessageView(props, ctx) {
415
415
  const store = ctx.getStore(MessageStore);
@@ -431,9 +431,6 @@ function LayoutView() {
431
431
  );
432
432
  }
433
433
 
434
- // Use LayoutView as the app's main view.
435
- app.main(LayoutView);
436
-
437
434
  // Connect the app.
438
435
  app.connect("#app");
439
436
  ```
@@ -537,15 +534,20 @@ const app = App({
537
534
  </div>
538
535
  );
539
536
  },
540
- });
541
-
542
- app.addStore(RouterStore, {
543
- hash: true, // Use hash-based routing (default false)
544
537
 
545
- // Here are a couple of routes to be rendered into our layout:
546
- routes: [
547
- { path: "/tasks", view: TasksView },
548
- { path: "/completed", view: CompletedView },
538
+ stores: [
539
+ {
540
+ store: RouterStore,
541
+ options: {
542
+ hash: true, // Use hash-based routing (default false)
543
+
544
+ // Here are a couple of routes to be rendered into our layout:
545
+ routes: [
546
+ { path: "/tasks", view: TasksView },
547
+ { path: "/completed", view: CompletedView },
548
+ ],
549
+ },
550
+ },
549
551
  ],
550
552
  });
551
553
  ```
@@ -553,25 +555,32 @@ app.addStore(RouterStore, {
553
555
  Routes can also be nested. Just like the main view and its routes, subroutes will be displayed in the outlet of their parent view.
554
556
 
555
557
  ```jsx
556
- app.addStore(RouterStore, {
557
- routes: [
558
+ const app = App({
559
+ stores: [
558
560
  {
559
- path: "/tasks",
560
- view: TasksView,
561
- routes: [
562
- { path: "/", view: TaskListView },
563
-
564
- // In routes, `{value}` is a dynamic value that matches anything,
565
- // and `{#value}` is a dynamic value that matches a number.
566
- { path: "/{#id}", view: TaskDetailsView },
567
- { path: "/{#id}/edit", view: TaskEditView },
568
-
569
- // If the route is any other than the ones defined above, redirect to the list.
570
- // Redirects support './' and '../' style relative paths.
571
- { path: "*", redirect: "./" },
572
- ],
561
+ store: RouterStore,
562
+ options: {
563
+ routes: [
564
+ {
565
+ path: "/tasks",
566
+ view: TasksView,
567
+ routes: [
568
+ { path: "/", view: TaskListView },
569
+
570
+ // In routes, `{value}` is a dynamic value that matches anything,
571
+ // and `{#value}` is a dynamic value that matches a number.
572
+ { path: "/{#id}", view: TaskDetailsView },
573
+ { path: "/{#id}/edit", view: TaskEditView },
574
+
575
+ // If the route is any other than the ones defined above, redirect to the list.
576
+ // Redirects support './' and '../' style relative paths.
577
+ { path: "*", redirect: "./" },
578
+ ],
579
+ },
580
+ { path: "/completed", view: CompletedView },
581
+ ],
582
+ },
573
583
  },
574
- { path: "/completed", view: CompletedView },
575
584
  ],
576
585
  });
577
586
  ```
@@ -606,22 +615,27 @@ Now, here are some route examples in the context of an app:
606
615
  import { App, RouterStore } from "@manyducks.co/dolla";
607
616
  import { PersonDetails, ThingIndex, ThingDetails, ThingEdit, ThingDelete } from "./components.js";
608
617
 
609
- const app = App();
610
-
611
- app.addStore(RouterStore, {
612
- routes: [
613
- { path: "/people/{name}", view: PersonDetails },
618
+ const app = App({
619
+ stores: [
614
620
  {
615
- // A `null` component with subroutes acts as a namespace for those subroutes.
616
- // Passing a view instead of `null` results in subroutes being rendered inside that view wherever `ctx.outlet()` is called.
617
- path: "/things",
618
- view: null,
619
- routes: [
620
- { path: "/", view: ThingIndex }, // matches `/things`
621
- { path: "/{#id}", view: ThingDetails }, // matches `/things/{#id}`
622
- { path: "/{#id}/edit", view: ThingEdit }, // matches `/things/{#id}/edit`
623
- { path: "/{#id}/delete", view: ThingDelete }, // matches `/things/{#id}/delete`
624
- ],
621
+ store: RouterStore,
622
+ options: {
623
+ routes: [
624
+ { path: "/people/{name}", view: PersonDetails },
625
+ {
626
+ // A `null` component with subroutes acts as a namespace for those subroutes.
627
+ // Passing a view instead of `null` results in subroutes being rendered inside that view wherever `ctx.outlet()` is called.
628
+ path: "/things",
629
+ view: null,
630
+ routes: [
631
+ { path: "/", view: ThingIndex }, // matches `/things`
632
+ { path: "/{#id}", view: ThingDetails }, // matches `/things/{#id}`
633
+ { path: "/{#id}/edit", view: ThingEdit }, // matches `/things/{#id}/edit`
634
+ { path: "/{#id}/delete", view: ThingDelete }, // matches `/things/{#id}/delete`
635
+ ],
636
+ },
637
+ ],
638
+ },
625
639
  },
626
640
  ],
627
641
  });
@@ -0,0 +1,44 @@
1
+ type EventListeners<E extends EventMap> = {
2
+ [K in keyof E]?: EventCallback<E, K>[];
3
+ };
4
+ export type EventCallback<E extends EventMap, K extends keyof E> = (event: EmittedEvent<E, K>) => void;
5
+ /**
6
+ * A map of event names and data values that their listener callbacks take.
7
+ */
8
+ export interface EventMap {
9
+ [name: string]: any;
10
+ }
11
+ /**
12
+ * A hub for subscribing to and emitting events. A good pattern when you want to notify several parts of your app
13
+ * at once when a condition changes in a central location. This is a similar pattern to Readable and Writable as far as
14
+ * observability goes, but with the added ability to emit multiple event types each with their own separate listeners.
15
+ */
16
+ export declare class EventEmitter<E extends EventMap = EventMap> {
17
+ listeners: EventListeners<E>;
18
+ /**
19
+ * Emit an event.
20
+ */
21
+ emit<K extends keyof E>(name: K, data: E[K]): void;
22
+ /**
23
+ * Listen for an event. The callback will be called whenever that event is emitted.
24
+ * Returns a function that will cancel this listener when called.
25
+ */
26
+ on<K extends keyof EventListeners<E>>(name: K, callback: EventCallback<E, K>): () => void;
27
+ /**
28
+ * Listen for the next emitted event. The callback will be called once the next time that event is emitted,
29
+ * and then never again. Returns a function that will cancel this listener when called.
30
+ */
31
+ once<K extends keyof EventListeners<E>>(name: K, callback: EventCallback<E, K>): () => void;
32
+ /**
33
+ * Cancel a listener by passing the callback that was originally used to register it.
34
+ */
35
+ off<K extends keyof EventListeners<E>>(name: K, callback: EventCallback<E, K>): void;
36
+ }
37
+ declare class EmittedEvent<E extends EventMap, K extends keyof E> {
38
+ /**
39
+ * Data object emitted with this event.
40
+ */
41
+ data: E[K];
42
+ constructor(data: E[K]);
43
+ }
44
+ export {};