intent.js
  1  "use strict";
  2  Object.defineProperty(exports, "__esModule", { value: true });
  3  exports.Continuous = exports.makeSidepackedIntent = exports.makeStaticContinuousIntentsOf = exports.makeStaticIntent = void 0;
  4  /**
  5   * Create a static intent.
  6   *
  7   * @param data - The data to wrap.
  8   * @returns A new static intent ready for use.
  9   */
 10  function makeStaticIntent(data) {
 11      const intent = {
 12          $kind: "$static",
 13          $data: data,
 14      };
 15      return intent;
 16  }
 17  exports.makeStaticIntent = makeStaticIntent;
 18  /**
 19   * Transform an array of data into an array of continuous static intents.
 20   *
 21   * @param elements - An array of data to wrap.
 22   * @returns A new static intent ready for use.
 23   */
 24  function makeStaticContinuousIntentsOf(elements) {
 25      const intents = new Array();
 26      for (const element of elements) {
 27          intents.push(makeStaticIntent(Continuous.of(element)));
 28      }
 29      return intents;
 30  }
 31  exports.makeStaticContinuousIntentsOf = makeStaticContinuousIntentsOf;
 32  /**
 33   * Create a sidepacked intent.
 34   *
 35   * @param data - The initial value to use before the provided intent is dispatched.
 36   * @param intent - The intent that JetEngine should resolve when rendered.
 37   * @returns A new sidepacked intent ready for use.
 38   */
 39  function makeSidepackedIntent(initial, intent) {
 40      const sidepackedIntent = {
 41          $kind: "$sidepacked",
 42          $initial: initial,
 43          $intent: intent,
 44      };
 45      return sidepackedIntent;
 46  }
 47  exports.makeSidepackedIntent = makeSidepackedIntent;
 48  // MARK: - Continuous
 49  /**
 50   * A async iterable which allows an intent implementation to vend data
 51   * which changes over time, such as the state of a buy button,
 52   * or database-backed shelves on a page.
 53   *
 54   * Use `Continuous` to specify that an intent embedded in a model,
 55   * or passed to a view, vends data which changes over time instead
 56   * of being calculated once at the time the intent is dispatched.
 57   *
 58   * ```typescript
 59   * export interface Page extends PageModel {
 60   *   readonly shelves: Intent<Continuous<Shelf>>[];
 61   * }
 62   * ```
 63   *
 64   * A continuous async iterable can be created with a single element.
 65   * This allows a model built around continuous intents to still cleanly
 66   * represent data which will not change after being displayed the first time.
 67   *
 68   * ```typescript
 69   * const page: Page = {
 70   *   pageMetrics: notInstrumented(NotInstrumentedMetricsType.PageMetrics),
 71   *   shelves: [
 72   *     makeStaticIntent(Continuous.of(Shelf(...))),
 73   *   ]
 74   * };
 75   * ```
 76   * A continuous async iterable can be created with another `AsyncIterable`
 77   * as a backing data source:
 78   *
 79   * ```typescript
 80   * async function* timer(
 81   *   interval: number,
 82   *   start: number = 0,
 83   *   limit: number? = undefined,
 84   * ): AsyncIterator<number> {
 85   *   for (let next = start; next != limit; next++) {
 86   *     yield next;
 87   *     await setTimeout(interval);
 88   *   }
 89   * }
 90   *
 91   * const countToTen = Continuous.contentsOf(timer(1000, 0, 10));
 92   * ```
 93   *
 94   * A single element continuous async iterable can be stringified to JSON
 95   * as long the element itself has a valid JSON representation. This is
 96   * especially useful when combined with `StaticIntent`.
 97   *
 98   * ```typescript
 99   * const shelfIntent = makeStaticIntent(Continuous.of(Shelf(...)));
100   * const jsonData = JSON.stringify(shelfIntent);
101   * ```
102   *
103   * __Important__: A continuous async iterable which wraps another
104   * async iterable cannot be directly JSON stringified.
105   */
106  class Continuous {
107      // MARK: - Constructors
108      /**
109       * Create a continuous async iterable with a single pre-determined element.
110       *
111       * @param element - A single element to yield from the new async iterable.
112       * @returns A new continuous async iterable ready to use.
113       */
114      static of(element) {
115          return new Continuous(new AsyncJust(element));
116      }
117      /**
118       * Create a continuous async iterable by wrapping an async iterable.
119       *
120       * __Important__: A continuous async iterable which wraps another
121       * async iterable cannot be directly JSON stringified.
122       *
123       * @param base - The async iterable to wrap.
124       * @returns A new continuous async iterable ready to use.
125       */
126      static contentsOf(base) {
127          return new Continuous(base);
128      }
129      /**
130       * Construct a continuous async iterable by wrapping an async iterable.
131       *
132       * @param base - The async iterable to wrap.
133       */
134      constructor(base) {
135          this.base = base;
136          // Indicate to native that the true content of this object is in the base field under direct bridging where toJSON is not called.
137          this["$wrappedField"] = "base";
138      }
139      // MARK: - JSON.stringify
140      toJSON() {
141          if (this.base instanceof AsyncJust) {
142              return this.base.toJSON();
143          }
144          else {
145              throw new TypeError("Continuous was not created with a single element");
146          }
147      }
148      // MARK: - AsyncIterable
149      async *[Symbol.asyncIterator]() {
150          yield* this.base;
151      }
152  }
153  exports.Continuous = Continuous;
154  /**
155   * An asynchronous iterable which yields a single element.
156   */
157  class AsyncJust {
158      // MARK: - Constructors
159      /**
160       * Construct an async iterable containing just the given element.
161       *
162       * @param element - The only element to yield.
163       */
164      constructor(element) {
165          this.element = element;
166          // Indicate to native that the true content of this object is in the element field under direct bridging where toJSON is not called.
167          this["$wrappedField"] = "element";
168      }
169      // MARK: - JSON.stringify
170      toJSON() {
171          return this.element;
172      }
173      // MARK: - AsyncIterable
174      async *[Symbol.asyncIterator]() {
175          yield this.element;
176      }
177  }
178  //# sourceMappingURL=intent.js.map