@xtia/jel 0.11.0 → 0.11.2

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
@@ -188,4 +188,120 @@ Emitters for this purpose can be Jel events, [@xtia/timeline](https://github.com
188
188
  import { animate } from "@xtia/timeline";
189
189
 
190
190
  button.style.opacity = animate(500).tween(0, 1);
191
- ```
191
+ ```
192
+
193
+ ## Custom streams
194
+
195
+ Several utilities are provided to create event streams from existing sources and custom emit logic.
196
+
197
+ ### `toEventEmitter(source)`
198
+
199
+ Creates an `EventEmitter<T>` from an `EmitterLike<T>`, a listen function (`(Handler<T>) => UnsubscribeFunc`), or an `EventSource` + event name pair.
200
+
201
+ * `EmitterLike<T>` is any object with a compatible `subscribe|listen` method
202
+ * `EventSource` is any object with common `addEventListener/removeEventListener|on/off` methods.
203
+
204
+ ```ts
205
+ import { toEventEmitter } from "@xtia/jel";
206
+
207
+ // EventSource + name:
208
+ const keypresses$ = toEventEmitter(window, "keydown");
209
+
210
+ keypresses$.map(ev => ev.key)
211
+ .listen(key => console.log(key, "pressed"));
212
+
213
+ // EmitterLike
214
+ function logEvents(emitter: EmitterLike<any>) {
215
+ // this function accepts Jel's EventEmitter, as well as RxJS
216
+ // streams and other compatible emitters
217
+ toEventEmitter(emitter).listen(value => console.log(value));
218
+ }
219
+ ```
220
+
221
+ ## createEventSource<T>()
222
+
223
+ Creates an EventEmitter<T> and a `emit(T)` function to control it.
224
+
225
+ ```ts
226
+ import { createEventSource } from "@xtia/jel";
227
+
228
+ function createGame() {
229
+ const winEmitPair = createEventSource<string>();
230
+
231
+ // <insert game logic>
232
+
233
+ // when someone wins:
234
+ winEmitPair.emit("player1");
235
+
236
+ return {
237
+ winEvent: winEmitPair.emitter
238
+ };
239
+ }
240
+
241
+ const game = createGame();
242
+ game.winEvent
243
+ .filter(winner => winner === me)
244
+ .apply(showConfetti);
245
+ ```
246
+
247
+ ## createEventsSource<Map>()
248
+
249
+ Creates an 'events' object and a `trigger(name, Map[name])` function to trigger specific events.
250
+
251
+ ```ts
252
+ import { createEventsSource } from "@xtia/jel";
253
+
254
+ type EventMap = {
255
+ end: { winner: string },
256
+ update: { state: GameState },
257
+ }
258
+
259
+ function createGame() {
260
+ const events = createEventsSource<EventMap>();
261
+
262
+ // when game ends
263
+ events.trigger("end", winnerName);
264
+
265
+ return {
266
+ events: events.emitters,
267
+ }
268
+ }
269
+ ```
270
+ ## createEventsProxy<Map>(source)
271
+
272
+ Creates an 'events' object from an `EventSource`.
273
+
274
+ ```ts
275
+ import { createEventsProxy } from "@xtia/jel";
276
+
277
+ const windowEvents = createEventsProxy<WindowEventMap>(window);
278
+ // (this windowEvents is exported from @xtia/jel for convenience)
279
+
280
+ windowEvents.keydown
281
+ .filter(ev => ev.key == "Enter")
282
+ .apply(() => console.log("Enter pressed"));
283
+ ```
284
+
285
+ ## `interval(ms)`
286
+
287
+ Emits a number, incremented by 1 each time, as long as any subscriptions are active.
288
+
289
+ ## `timeout(ms)`
290
+
291
+ Emits once after the specified time.
292
+
293
+ ## `animationFrames`
294
+
295
+ Emits *delta times* from a `requestAnimationFrame()` loop, as long as any subscriptions are active.
296
+
297
+ ```ts
298
+ import { animationFrames } from "@xtia.jel";
299
+
300
+ animationFrames.listen(delta => {
301
+ game.tick(delta);
302
+ });
303
+
304
+ ## SubjectEmitter
305
+
306
+ Creates a manually-controlled emitter that maintains its last emitted value (`em.value`), emits it immediately to
307
+ and new subscription and can be updated with `em.next(value)`.
@@ -1,6 +1,6 @@
1
1
  import { toEventEmitter } from "./emitter.js";
2
2
  import { attribsProxy, createEventsProxy, styleProxy } from "./proxy";
3
- import { entityDataSymbol, isContent, isJelEntity, isReactiveSource } from "./util";
3
+ import { entityDataSymbol, isContent, isJelEntity, isReactiveSource } from "./util.js";
4
4
  const elementWrapCache = new WeakMap();
5
5
  const recursiveAppend = (parent, c) => {
6
6
  if (c === null || c === undefined)
@@ -456,10 +456,9 @@ export const animationFrames = (() => {
456
456
  let rafId = null;
457
457
  let lastTime = null;
458
458
  const frame = (time) => {
459
- if (lastTime === null)
460
- lastTime = time;
461
459
  rafId = requestAnimationFrame(frame);
462
- const elapsed = time - lastTime;
460
+ const elapsed = time - (lastTime !== null && lastTime !== void 0 ? lastTime : time);
461
+ lastTime = time;
463
462
  emit(elapsed);
464
463
  };
465
464
  rafId = requestAnimationFrame(frame);
@@ -0,0 +1,4 @@
1
+ import { DomEntity } from "./types";
2
+ export declare const $body: DomEntity<HTMLElement>;
3
+ export declare const windowEvents: import("./types").EventEmitterMap<WindowEventMap>;
4
+ export declare const documentEvents: import("./types").EventEmitterMap<DocumentEventMap>;
package/lib/helpers.js ADDED
@@ -0,0 +1,5 @@
1
+ import { $ } from "./element";
2
+ import { createEventsProxy } from "./proxy";
3
+ export const $body = "document" in globalThis ? $(document.body) : undefined;
4
+ export const windowEvents = createEventsProxy(window);
5
+ export const documentEvents = createEventsProxy(document);
package/lib/index.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ export { $ } from "./element";
2
+ export { DomEntity, ElementClassDescriptor, ElementDescriptor, DOMContent, DomHelper, StyleAccessor, JelEntity, EventEmitterMap, EmitterLike, CSSValue } from "./types";
3
+ export { createEntity } from "./util";
4
+ export { createEventSource, createEventsSource, interval, timeout, animationFrames, SubjectEmitter, toEventEmitter, type EventEmitter, type EventRecording, type EventRecorder, combineEmitters } from "./emitter";
5
+ export { createEventsProxy } from "./proxy";
6
+ export { $body, windowEvents } from "./helpers";
package/lib/index.js ADDED
@@ -0,0 +1,5 @@
1
+ export { $ } from "./element";
2
+ export { createEntity } from "./util";
3
+ export { createEventSource, createEventsSource, interval, timeout, animationFrames, SubjectEmitter, toEventEmitter, combineEmitters } from "./emitter";
4
+ export { createEventsProxy } from "./proxy";
5
+ export { $body, windowEvents } from "./helpers";
package/package.json CHANGED
@@ -1,28 +1,44 @@
1
1
  {
2
2
  "name": "@xtia/jel",
3
- "version": "0.11.0",
4
- "repository": {
5
- "url": "https://github.com/tiadrop/jel-ts",
6
- "type": "github"
7
- },
3
+ "version": "0.11.2",
4
+ "description": "Lightweight DOM manipulation, componentisation and reactivity",
5
+ "keywords": [
6
+ "dom",
7
+ "reactive",
8
+ "streams",
9
+ "reactive-programming",
10
+ "frontend",
11
+ "ui",
12
+ "framework"
13
+ ],
14
+ "types": "./lib/index.d.ts",
15
+ "main": "./lib/index.js",
8
16
  "sideEffects": false,
9
- "types": "./index.d.ts",
10
- "main": "./index.js",
11
17
  "exports": {
12
18
  ".": {
13
- "types": "./index.d.ts",
14
- "default": "./index.js"
19
+ "types": "./lib/index.d.ts",
20
+ "default": "./lib/index.js"
15
21
  },
16
- "./internal/*": null
22
+ "./lib/*": null
17
23
  },
18
24
  "scripts": {
19
- "prepublishOnly": "cp ../README.md .",
20
- "postpublish": "rm README.md"
25
+ "build": "tsc",
26
+ "watch-demo": "webpack --watch",
27
+ "prepublishOnly": "tsc"
21
28
  },
22
- "description": "Lightweight DOM manipulation, componentisation and reactivity",
23
- "keywords": [
24
- "dom"
29
+ "repository": {
30
+ "url": "https://github.com/tiadrop/jel-ts",
31
+ "type": "github"
32
+ },
33
+ "files": [
34
+ "lib/"
25
35
  ],
26
36
  "author": "Aleta Lovelace",
27
- "license": "MIT"
37
+ "license": "MIT",
38
+ "devDependencies": {
39
+ "ts-loader": "^9.5.1",
40
+ "typescript": "^5.9.3",
41
+ "webpack": "^5.95.0",
42
+ "webpack-cli": "^5.1.4"
43
+ }
28
44
  }
package/index.d.ts DELETED
@@ -1,9 +0,0 @@
1
- import { $ } from "./internal/element";
2
- import { DomEntity } from "./internal/types";
3
- export { DomEntity, ElementClassDescriptor, ElementDescriptor, DOMContent, DomHelper, StyleAccessor, JelEntity, EventEmitterMap, EmitterLike, CSSValue } from "./internal/types";
4
- export { createEntity } from "./internal/util";
5
- export { createEventSource, createEventsSource, interval, timeout, animationFrames, SubjectEmitter, toEventEmitter, type EventEmitter, type EventRecording, type EventRecorder, combineEmitters } from "./internal/emitter";
6
- export { createEventsProxy } from "./internal/proxy";
7
- export { $ };
8
- export declare const $body: DomEntity<HTMLElement>;
9
- export declare const windowEvents: import(".").EventEmitterMap<WindowEventMap>;
package/index.js DELETED
@@ -1,8 +0,0 @@
1
- import { $ } from "./internal/element";
2
- import { createEventsProxy } from "./internal/proxy";
3
- export { createEntity } from "./internal/util";
4
- export { createEventSource, createEventsSource, interval, timeout, animationFrames, SubjectEmitter, toEventEmitter, combineEmitters } from "./internal/emitter";
5
- export { createEventsProxy } from "./internal/proxy";
6
- export { $ };
7
- export const $body = "document" in globalThis ? $(document.body) : undefined;
8
- export const windowEvents = createEventsProxy(window);
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes