@joycostudio/susano 0.1.0 → 0.1.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
@@ -6,6 +6,172 @@ Asset load orchestration made easy.
6
6
  pnpm add @joycostudio/susano
7
7
  ```
8
8
 
9
+ ## Quick Start
10
+
11
+ ```ts
12
+ import { susano } from '@joycostudio/susano'
13
+
14
+ // Queue assets
15
+ susano.add('/hero.png', { type: 'image' })
16
+ susano.add('/intro.mp4', { type: 'video' })
17
+
18
+ // Start loading
19
+ susano.start({
20
+ onProgress: ({ value }) => console.log(`${Math.round(value * 100)}%`),
21
+ onCompleted: () => console.log('All assets loaded!'),
22
+ })
23
+ ```
24
+
25
+ ## API
26
+
27
+ ### `susano` singleton
28
+
29
+ A pre-configured instance with built-in loaders for `image`, `video`, `audio`, and `generic` types.
30
+
31
+ ### `add(url, { type, loaderArgs? })`
32
+
33
+ Queue an asset for batch loading. Returns the loader instance.
34
+
35
+ ```ts
36
+ const img = susano.add('/photo.png', {
37
+ type: 'image',
38
+ loaderArgs: { srcSet: '480w.png 480w, 800w.png 800w', sizes: '(max-width: 600px) 480px, 800px' },
39
+ })
40
+ ```
41
+
42
+ ### `load(url, { type, loaderArgs? })`
43
+
44
+ Load a single asset immediately (standalone, outside the batch queue). Returns the loader instance.
45
+
46
+ ```ts
47
+ const img = susano.load('/standalone.png', { type: 'image' })
48
+ ```
49
+
50
+ ### `start({ onProgress?, onCompleted? })`
51
+
52
+ Start loading all queued assets. Emits `start`, `progress`, and `completed` events.
53
+
54
+ ```ts
55
+ susano.start({
56
+ onProgress: ({ value, item }) => {
57
+ // value: 0 to 1
58
+ },
59
+ onCompleted: (susano) => {
60
+ // all assets loaded
61
+ },
62
+ })
63
+ ```
64
+
65
+ ### `registerLoader(type, loader)`
66
+
67
+ Register a custom loader class for a given type.
68
+
69
+ ```ts
70
+ susano.registerLoader('custom', CustomLoader)
71
+ ```
72
+
73
+ ## Built-in Loaders
74
+
75
+ ### `image`
76
+
77
+ Loads images via `HTMLImageElement`.
78
+
79
+ | Option | Type | Description |
80
+ | -------- | -------- | ----------------------------- |
81
+ | `srcSet` | `string` | Maps to `img.srcset` |
82
+ | `sizes` | `string` | Maps to `img.sizes` |
83
+
84
+ ```ts
85
+ susano.add('/photo.png', {
86
+ type: 'image',
87
+ loaderArgs: { srcSet: '/photo-2x.png 2x', sizes: '100vw' },
88
+ })
89
+ ```
90
+
91
+ ### `video`
92
+
93
+ Loads video via `HTMLVideoElement`.
94
+
95
+ | Option | Type | Default | Description |
96
+ | ----------- | ---------------------------------- | ----------- | ---------------------------------- |
97
+ | `video` | `HTMLVideoElement` | new element | Existing video element to load into |
98
+ | `loadEvent` | `'canplay'` \| `'canplaythrough'` | `'canplay'` | Event that signals load completion |
99
+
100
+ ```ts
101
+ susano.add('/intro.mp4', {
102
+ type: 'video',
103
+ loaderArgs: { loadEvent: 'canplaythrough' },
104
+ })
105
+ ```
106
+
107
+ ### `audio`
108
+
109
+ Loads audio via `HTMLAudioElement`.
110
+
111
+ | Option | Type | Default | Description |
112
+ | ----------- | ---------------------------------- | ----------- | ---------------------------------- |
113
+ | `audio` | `HTMLAudioElement` | new element | Existing audio element to load into |
114
+ | `loadEvent` | `'canplay'` \| `'canplaythrough'` | `'canplay'` | Event that signals load completion |
115
+
116
+ ```ts
117
+ susano.add('/music.mp3', {
118
+ type: 'audio',
119
+ loaderArgs: { loadEvent: 'canplaythrough' },
120
+ })
121
+ ```
122
+
123
+ ### `generic`
124
+
125
+ Fully custom loader. Requires a `loadFn` callback.
126
+
127
+ | Option | Type | Description |
128
+ | -------- | ------------- | ------------------------------------ |
129
+ | `loadFn` | `GenericLoadFn` | **Required.** Custom load function |
130
+
131
+ The `loadFn` receives `{ url, done, error, progress }`:
132
+
133
+ ```ts
134
+ susano.add('/data.json', {
135
+ type: 'generic',
136
+ loaderArgs: {
137
+ loadFn: ({ url, done, error, progress }) => {
138
+ fetch(url)
139
+ .then((res) => res.json())
140
+ .then((data) => done(data))
141
+ .catch((err) => error(err))
142
+ },
143
+ },
144
+ })
145
+ ```
146
+
147
+ ## Events
148
+
149
+ The `susano` instance extends `TinyEmitter` and emits:
150
+
151
+ | Event | Payload | Description |
152
+ | ----------- | ---------------------------------------------------- | ------------------------- |
153
+ | `start` | `susano` | Batch loading started |
154
+ | `progress` | `{ value: number, item: SusanoLoader, susano }` | An asset finished loading |
155
+ | `completed` | `susano` | All assets loaded |
156
+
157
+ Individual loader instances also emit `loaded` and `progress` events.
158
+
159
+ ## Batched vs Standalone Loading
160
+
161
+ **Batched** — queue multiple assets with `add()`, then call `start()` to load them all. Progress is tracked across the entire batch.
162
+
163
+ ```ts
164
+ susano.add('/a.png', { type: 'image' })
165
+ susano.add('/b.mp4', { type: 'video' })
166
+ susano.start({ onCompleted: () => console.log('done') })
167
+ ```
168
+
169
+ **Standalone** — use `load()` to immediately load a single asset without affecting the batch queue.
170
+
171
+ ```ts
172
+ const item = susano.load('/lazy.png', { type: 'image' })
173
+ ```
174
+
9
175
  ## 🤖 Automatic Workflows
10
176
 
11
177
  1. **Release Workflow** (`.github/workflows/release.yml`): Automates the release process using Changesets. When enabled, it will automatically create release pull requests and publish to npm when changes are pushed to the main branch.
package/dist/index.d.mts CHANGED
@@ -11,9 +11,14 @@ declare class SusanoLoader<T> extends TinyEmitter implements ISusanoLoader<T> {
11
11
  config: SusanoLoaderConfig<T>;
12
12
  weight: number;
13
13
  progress: number;
14
+ promise: Promise<T>;
15
+ private _resolve;
16
+ private _reject;
14
17
  constructor(url: string, _cnfg?: SusanoLoaderConfig<T>);
15
18
  load(): Promise<T>;
16
19
  _onLoaded(): void;
20
+ _onError(error: unknown): void;
21
+ private _resetPromise;
17
22
  _onProgress(value: number): void;
18
23
  /**
19
24
  * This is ment to be used as a way to attach to master loader events
@@ -143,4 +148,4 @@ declare const susano: Susano<{
143
148
 
144
149
  declare const VERSION: string;
145
150
 
146
- export { AudioLoader, type GenericLoadFn, GenericLoader, ImageLoader, type LoaderMap, type LoaderTypes, type ProgressEventArgs, Susano, type SusanoAudioLoaderConfig, type SusanoGenericLoaderConfig, type SusanoImageLoaderConfig, type SusanoVideoLoaderConfig, VERSION, VideoLoader, susano };
151
+ export { AudioLoader, type GenericLoadFn, GenericLoader, type ISusanoLoader, ImageLoader, type LoaderMap, type LoaderTypes, type ProgressEventArgs, Susano, type SusanoAudioLoaderConfig, type SusanoGenericLoaderConfig, type SusanoImageLoaderConfig, SusanoLoader, type SusanoLoaderConfig, type SusanoVideoLoaderConfig, VERSION, VideoLoader, susano };
package/dist/index.d.ts CHANGED
@@ -11,9 +11,14 @@ declare class SusanoLoader<T> extends TinyEmitter implements ISusanoLoader<T> {
11
11
  config: SusanoLoaderConfig<T>;
12
12
  weight: number;
13
13
  progress: number;
14
+ promise: Promise<T>;
15
+ private _resolve;
16
+ private _reject;
14
17
  constructor(url: string, _cnfg?: SusanoLoaderConfig<T>);
15
18
  load(): Promise<T>;
16
19
  _onLoaded(): void;
20
+ _onError(error: unknown): void;
21
+ private _resetPromise;
17
22
  _onProgress(value: number): void;
18
23
  /**
19
24
  * This is ment to be used as a way to attach to master loader events
@@ -143,4 +148,4 @@ declare const susano: Susano<{
143
148
 
144
149
  declare const VERSION: string;
145
150
 
146
- export { AudioLoader, type GenericLoadFn, GenericLoader, ImageLoader, type LoaderMap, type LoaderTypes, type ProgressEventArgs, Susano, type SusanoAudioLoaderConfig, type SusanoGenericLoaderConfig, type SusanoImageLoaderConfig, type SusanoVideoLoaderConfig, VERSION, VideoLoader, susano };
151
+ export { AudioLoader, type GenericLoadFn, GenericLoader, type ISusanoLoader, ImageLoader, type LoaderMap, type LoaderTypes, type ProgressEventArgs, Susano, type SusanoAudioLoaderConfig, type SusanoGenericLoaderConfig, type SusanoImageLoaderConfig, SusanoLoader, type SusanoLoaderConfig, type SusanoVideoLoaderConfig, VERSION, VideoLoader, susano };
package/dist/index.js CHANGED
@@ -3,7 +3,7 @@
3
3
  var tinyEmitter = require('tiny-emitter');
4
4
 
5
5
  // package.json
6
- var version = "0.1.0";
6
+ var version = "0.1.2";
7
7
  var SusanoLoader = class extends tinyEmitter.TinyEmitter {
8
8
  constructor(url, _cnfg = {}) {
9
9
  super();
@@ -13,6 +13,7 @@ var SusanoLoader = class extends tinyEmitter.TinyEmitter {
13
13
  this.config = _cnfg;
14
14
  this.weight = 1;
15
15
  this.progress = 0;
16
+ this._resetPromise();
16
17
  }
17
18
  load() {
18
19
  throw new Error("Method not implemented");
@@ -20,9 +21,22 @@ var SusanoLoader = class extends tinyEmitter.TinyEmitter {
20
21
  _onLoaded() {
21
22
  this.loaded = true;
22
23
  this.progress = 1;
24
+ this._resolve(this.content);
23
25
  this.emit("loaded", this);
24
26
  this.config.onLoaded?.(this);
25
27
  }
28
+ _onError(error) {
29
+ this._reject(error);
30
+ this.progress = 0;
31
+ this._resetPromise();
32
+ this.emit("error", error);
33
+ }
34
+ _resetPromise() {
35
+ this.promise = new Promise((resolve, reject) => {
36
+ this._resolve = resolve;
37
+ this._reject = reject;
38
+ });
39
+ }
26
40
  _onProgress(value) {
27
41
  this.progress = value;
28
42
  this.emit("progress", this);
@@ -54,21 +68,16 @@ var ImageLoader = class extends SusanoLoader {
54
68
  this.sizes = cnfg.sizes;
55
69
  }
56
70
  load() {
57
- return new Promise((resolve, reject) => {
58
- if (this.loaded) {
59
- this._onLoaded.call(this);
60
- resolve(this.content);
61
- return;
62
- }
63
- if (this.srcSet) this.content.srcset = this.srcSet;
64
- if (this.sizes) this.content.sizes = this.sizes;
65
- this.content.src = this.url;
66
- this.content.onload = () => {
67
- this._onLoaded.call(this);
68
- resolve(this.content);
69
- };
70
- this.content.onerror = (e) => reject(e);
71
- });
71
+ if (this.loaded) {
72
+ this._onLoaded();
73
+ return this.promise;
74
+ }
75
+ if (this.srcSet) this.content.srcset = this.srcSet;
76
+ if (this.sizes) this.content.sizes = this.sizes;
77
+ this.content.src = this.url;
78
+ this.content.onload = () => this._onLoaded();
79
+ this.content.onerror = (e) => this._onError(e);
80
+ return this.promise;
72
81
  }
73
82
  };
74
83
  ImageLoader.type = "image";
@@ -81,20 +90,15 @@ var VideoLoader = class extends SusanoLoader {
81
90
  this.loadEvent = cnfg.loadEvent || "canplay";
82
91
  }
83
92
  load() {
84
- return new Promise((resolve, reject) => {
85
- const video = this.content;
86
- if (this.loaded) {
87
- this._onLoaded.call(this);
88
- resolve(this.content);
89
- return;
90
- }
91
- video.src = this.url;
92
- video.addEventListener(this.loadEvent, () => {
93
- this._onLoaded.call(this);
94
- resolve(this.content);
95
- });
96
- video.addEventListener("error", (e) => reject(e));
97
- });
93
+ if (this.loaded) {
94
+ this._onLoaded();
95
+ return this.promise;
96
+ }
97
+ const el = this.content;
98
+ el.src = this.url;
99
+ el.addEventListener(this.loadEvent, () => this._onLoaded(), { once: true });
100
+ el.addEventListener("error", (e) => this._onError(e), { once: true });
101
+ return this.promise;
98
102
  }
99
103
  };
100
104
  VideoLoader.type = "video";
@@ -107,20 +111,15 @@ var AudioLoader = class extends SusanoLoader {
107
111
  this.loadEvent = cnfg.loadEvent || "canplay";
108
112
  }
109
113
  load() {
110
- return new Promise((resolve, reject) => {
111
- const audio = this.content;
112
- if (this.loaded) {
113
- this._onLoaded.call(this);
114
- resolve(this.content);
115
- return;
116
- }
117
- audio.src = this.url;
118
- audio.addEventListener(this.loadEvent, () => {
119
- this._onLoaded.call(this);
120
- resolve(this.content);
121
- });
122
- audio.addEventListener("error", (e) => reject(e));
123
- });
114
+ if (this.loaded) {
115
+ this._onLoaded();
116
+ return this.promise;
117
+ }
118
+ const el = this.content;
119
+ el.src = this.url;
120
+ el.addEventListener(this.loadEvent, () => this._onLoaded(), { once: true });
121
+ el.addEventListener("error", (e) => this._onError(e), { once: true });
122
+ return this.promise;
124
123
  }
125
124
  };
126
125
  AudioLoader.type = "audio";
@@ -132,30 +131,25 @@ var GenericLoader = class extends SusanoLoader {
132
131
  this.loadFn = cnfg.loadFn;
133
132
  }
134
133
  load() {
135
- return new Promise((resolve, reject) => {
136
- if (!this.loadFn) {
137
- reject(new Error("No load function provided"));
138
- return;
139
- }
140
- if (this.loaded) {
141
- this._onLoaded.call(this);
142
- resolve(this.content);
143
- return;
144
- }
145
- this.loadFn({
146
- url: this.url,
147
- done: (generic) => {
148
- this.content = generic;
149
- this._onLoaded.call(this);
150
- resolve(generic);
151
- },
152
- error: reject,
153
- /* 0 to 1 */
154
- progress: (value) => {
155
- this._onProgress.call(this, value);
156
- }
157
- });
134
+ if (!this.loadFn) {
135
+ this._onError(new Error("No load function provided"));
136
+ return this.promise;
137
+ }
138
+ if (this.loaded) {
139
+ this._onLoaded();
140
+ return this.promise;
141
+ }
142
+ this.loadFn({
143
+ url: this.url,
144
+ done: (generic) => {
145
+ this.content = generic;
146
+ this._onLoaded();
147
+ },
148
+ error: (err) => this._onError(err),
149
+ /* 0 to 1 */
150
+ progress: (value) => this._onProgress(value)
158
151
  });
152
+ return this.promise;
159
153
  }
160
154
  };
161
155
  GenericLoader.type = "generic";
@@ -243,8 +237,13 @@ susano.registerLoader(GenericLoader.type, GenericLoader);
243
237
  // packages/core/index.ts
244
238
  var VERSION = version;
245
239
 
240
+ exports.AudioLoader = AudioLoader;
241
+ exports.GenericLoader = GenericLoader;
242
+ exports.ImageLoader = ImageLoader;
246
243
  exports.Susano = Susano;
244
+ exports.SusanoLoader = SusanoLoader;
247
245
  exports.VERSION = VERSION;
246
+ exports.VideoLoader = VideoLoader;
248
247
  exports.susano = susano;
249
248
  //# sourceMappingURL=index.js.map
250
249
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../package.json","../packages/core/loaders/loader.ts","../packages/core/loaders/image.ts","../packages/core/loaders/video.ts","../packages/core/loaders/audio.ts","../packages/core/loaders/generic.ts","../packages/core/core.tsx","../packages/core/index.ts"],"names":["TinyEmitter"],"mappings":"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","file":"index.js","sourcesContent":["{\n \"name\": \"@joycostudio/susano\",\n \"publishConfig\": {\n \"registry\": \"https://registry.npmjs.org\",\n \"access\": \"public\"\n },\n \"version\": \"0.1.0\",\n \"description\": \"Asset load orchestration made easy\",\n \"main\": \"dist/index.js\",\n \"module\": \"dist/index.mjs\",\n \"types\": \"dist/index.d.ts\",\n \"files\": [\n \"dist\"\n ],\n \"scripts\": {\n \"build\": \"tsup\",\n \"dev\": \"concurrently \\\"tsup --watch\\\" \\\"cd templates/basic && pnpm dev\\\"\",\n \"typecheck\": \"tsc --noEmit\",\n \"version:package\": \"pnpm changeset version\",\n \"release\": \"pnpm build && pnpm changeset publish\",\n \"lint\": \"eslint -c ./eslint.config.mjs . --fix --no-cache\"\n },\n \"packageManager\": \"pnpm@10.29.2\",\n \"author\": \"@joycostudio\",\n \"license\": \"ISC\",\n \"devDependencies\": {\n \"@changesets/cli\": \"^2.27.11\",\n \"@eslint/js\": \"^9.18.0\",\n \"@types/node\": \"^20.11.24\",\n \"@types/react\": \"^18.2.61\",\n \"@typescript-eslint/eslint-plugin\": \"^8.21.0\",\n \"@typescript-eslint/parser\": \"^8.21.0\",\n \"concurrently\": \"^9.1.2\",\n \"eslint\": \"^9.18.0\",\n \"eslint-config-prettier\": \"^10.0.1\",\n \"eslint-plugin-prettier\": \"^5.2.3\",\n \"eslint-plugin-react\": \"^7.37.4\",\n \"eslint-plugin-react-compiler\": \"19.0.0-beta-decd7b8-20250118\",\n \"globals\": \"^15.14.0\",\n \"prettier\": \"^3.4.2\",\n \"react\": \"^18.2.0\",\n \"tsup\": \"^8.0.2\",\n \"typescript\": \"^5.7.3\",\n \"typescript-eslint\": \"^8.21.0\"\n },\n \"peerDependencies\": {\n \"react\": \">=16.8.0\"\n },\n \"dependencies\": {\n \"tiny-emitter\": \"^2.1.0\"\n }\n}","import { TinyEmitter } from 'tiny-emitter'\n\nexport type SusanoLoaderConfig<T> = {\n onLoaded?: (loader: SusanoLoader<T>) => void\n onProgress?: (loader: SusanoLoader<T>) => void\n}\n\nexport class SusanoLoader<T> extends TinyEmitter implements ISusanoLoader<T> {\n public url: string\n public loaded: boolean\n public content: T\n public config: SusanoLoaderConfig<T>\n public weight: number\n public progress: number\n\n constructor(url: string, _cnfg: SusanoLoaderConfig<T> = {}) {\n super()\n this.url = url\n this.loaded = false\n this.content = null as unknown as T\n this.config = _cnfg\n this.weight = 1\n this.progress = 0\n }\n\n load(): Promise<T> {\n throw new Error('Method not implemented')\n }\n\n _onLoaded() {\n this.loaded = true\n this.progress = 1\n this.emit('loaded', this)\n this.config.onLoaded?.(this)\n }\n\n _onProgress(value: number) {\n this.progress = value\n this.emit('progress', this)\n this.config.onProgress?.(this)\n }\n\n /**\n * This is ment to be used as a way to attach to master loader events\n */\n _appendConfig(cnfg: SusanoLoaderConfig<T>) {\n const _onLoaded = this.config.onLoaded\n this.config.onLoaded = (loader) => {\n _onLoaded?.(loader)\n cnfg.onLoaded?.(loader)\n }\n\n const _onProgress = this.config.onProgress\n\n this.config.onProgress = (loader) => {\n _onProgress?.(loader)\n cnfg.onProgress?.(loader)\n }\n }\n}\n\nexport interface ISusanoLoader<T> {\n load: () => Promise<T>\n}\n","import { ISusanoLoader, SusanoLoaderConfig, SusanoLoader } from './loader'\n\nexport type SusanoImageLoaderConfig = SusanoLoaderConfig<HTMLImageElement> & {\n srcSet?: string\n sizes?: string\n}\n\nexport class ImageLoader extends SusanoLoader<HTMLImageElement> implements ISusanoLoader<HTMLImageElement> {\n public static type = 'image' as const\n public srcSet?: string\n public sizes?: string\n\n constructor(url: string, cnfg: SusanoImageLoaderConfig = {}) {\n super(url, cnfg)\n this.content = new Image()\n this.srcSet = cnfg.srcSet\n this.sizes = cnfg.sizes\n }\n\n load(): Promise<HTMLImageElement> {\n return new Promise((resolve, reject) => {\n if (this.loaded) {\n this._onLoaded.call(this)\n resolve(this.content)\n return\n }\n\n if (this.srcSet) this.content.srcset = this.srcSet\n if (this.sizes) this.content.sizes = this.sizes\n this.content.src = this.url\n\n this.content.onload = () => {\n this._onLoaded.call(this)\n resolve(this.content)\n }\n\n this.content.onerror = (e) => reject(e)\n })\n }\n}\n","import { ISusanoLoader, SusanoLoaderConfig, SusanoLoader } from './loader'\n\ntype LoadEvent = 'canplay' | 'canplaythrough'\n\nexport type SusanoVideoLoaderConfig = SusanoLoaderConfig<HTMLVideoElement> & {\n video?: HTMLVideoElement\n loadEvent?: LoadEvent\n}\n\nexport class VideoLoader extends SusanoLoader<HTMLVideoElement> implements ISusanoLoader<HTMLVideoElement> {\n public static type = 'video' as const\n public loadEvent: LoadEvent\n\n constructor(url: string, cnfg: SusanoVideoLoaderConfig = {}) {\n super(url, cnfg)\n this.content = cnfg.video || document.createElement('video')\n this.loadEvent = cnfg.loadEvent || 'canplay'\n }\n\n load(): Promise<HTMLVideoElement> {\n return new Promise((resolve, reject) => {\n const video = this.content\n\n if (this.loaded) {\n this._onLoaded.call(this)\n resolve(this.content)\n return\n }\n\n video.src = this.url\n\n video.addEventListener(this.loadEvent, () => {\n this._onLoaded.call(this)\n resolve(this.content)\n })\n\n video.addEventListener('error', (e) => reject(e))\n })\n }\n}\n","import { ISusanoLoader, SusanoLoaderConfig, SusanoLoader } from './loader'\n\ntype LoadEvent = 'canplay' | 'canplaythrough'\n\nexport type SusanoAudioLoaderConfig = SusanoLoaderConfig<HTMLAudioElement> & {\n audio?: HTMLAudioElement\n loadEvent?: LoadEvent\n}\n\nexport class AudioLoader extends SusanoLoader<HTMLAudioElement> implements ISusanoLoader<HTMLAudioElement> {\n public static type = 'audio' as const\n public loadEvent: LoadEvent\n\n constructor(url: string, cnfg: SusanoAudioLoaderConfig = {}) {\n super(url, cnfg)\n this.content = cnfg.audio || document.createElement('audio')\n this.loadEvent = cnfg.loadEvent || 'canplay'\n }\n\n load(): Promise<HTMLAudioElement> {\n return new Promise((resolve, reject) => {\n const audio = this.content\n\n if (this.loaded) {\n this._onLoaded.call(this)\n resolve(this.content)\n return\n }\n\n audio.src = this.url\n\n audio.addEventListener(this.loadEvent, () => {\n this._onLoaded.call(this)\n resolve(this.content)\n })\n\n audio.addEventListener('error', (e) => reject(e))\n })\n }\n}\n","import { SusanoLoader, SusanoLoaderConfig } from './loader'\n\nexport type GenericLoadFn = (config: {\n url: string\n done: (generic: any) => void\n error: (error: Error) => void\n progress: (progress: number) => void\n}) => void\n\nexport type SusanoGenericLoaderConfig = SusanoLoaderConfig<any> & {\n loadFn: GenericLoadFn\n}\n\nexport class GenericLoader extends SusanoLoader<any> {\n public static type = 'generic' as const\n public loadFn: GenericLoadFn\n\n constructor(url: string, cnfg: SusanoGenericLoaderConfig) {\n super(url, cnfg)\n this.loadFn = cnfg.loadFn\n }\n\n load(): Promise<any> {\n return new Promise((resolve, reject) => {\n if (!this.loadFn) {\n reject(new Error('No load function provided'))\n return\n }\n\n if (this.loaded) {\n this._onLoaded.call(this)\n resolve(this.content)\n return\n }\n\n this.loadFn({\n url: this.url,\n done: (generic: any) => {\n this.content = generic\n this._onLoaded.call(this)\n resolve(generic)\n },\n error: reject,\n /* 0 to 1 */\n progress: (value: number) => {\n this._onProgress.call(this, value)\n },\n })\n })\n }\n}\n","import { TinyEmitter } from 'tiny-emitter'\nimport { SusanoLoader } from './loaders/loader'\nimport { ImageLoader, type SusanoImageLoaderConfig } from './loaders/image'\nimport { VideoLoader, type SusanoVideoLoaderConfig } from './loaders/video'\nimport { AudioLoader, type SusanoAudioLoaderConfig } from './loaders/audio'\nimport { GenericLoader, type GenericLoadFn, type SusanoGenericLoaderConfig } from './loaders/generic'\n\nexport type LoaderTypes = {\n [K: string]: {\n type: typeof K\n loader: typeof SusanoLoader<any>\n }\n}\n\nexport type LoaderMap<T extends LoaderTypes> = {\n [K in keyof T]: T[K]['loader']\n}\n\nexport type ProgressEventArgs = {\n value: number\n item: SusanoLoader<unknown>\n susano: Susano<any>\n}\n\n/**\n * Main loader class that manages loading of different asset types\n * @template T Type definition for the loaders to be used, extending LoaderTypes\n * @extends TinyEmitter\n */\nexport class Susano<T extends LoaderTypes> extends TinyEmitter {\n private loaders: LoaderMap<T> = {} as LoaderMap<T>\n public queue: InstanceType<T[keyof T]['loader']>[] = []\n public active: InstanceType<T[keyof T]['loader']>[] = []\n public items: Map<string, InstanceType<T[keyof T]['loader']>> = new Map()\n public loadCount: number = 0\n public loadLength: number = 0\n\n constructor() {\n super()\n }\n\n add<K extends keyof T>(\n url: string,\n cnfg: {\n type: K\n loaderArgs?: ConstructorParameters<T[K]['loader']>[1]\n }\n ): InstanceType<T[K]['loader']> {\n const Loader = this.loaders[cnfg.type]\n\n if (!Loader) throw new Error(`Loader for type ${String(cnfg.type)} not found`)\n\n let item = this.items.get(url)\n\n if (!item) {\n item = new Loader(url, cnfg.loaderArgs) as InstanceType<T[K]['loader']>\n this.items.set(url, item)\n } else if (cnfg.loaderArgs) {\n item._appendConfig(cnfg.loaderArgs)\n }\n\n this.queue.push(item)\n\n return item\n }\n\n load<K extends keyof T>(\n url: string,\n cnfg: {\n type: K\n loaderArgs?: ConstructorParameters<T[K]['loader']>[1]\n }\n ) {\n const Loader = this.loaders[cnfg.type]\n if (!Loader) throw new Error(`Loader for type ${String(cnfg.type)} not found`)\n\n let item = this.items.get(url)\n\n if (!item) {\n item = new Loader(url, cnfg.loaderArgs) as InstanceType<T[K]['loader']>\n this.items.set(url, item)\n } else if (cnfg.loaderArgs) {\n item._appendConfig(cnfg.loaderArgs)\n }\n\n item.load()\n\n return item\n }\n\n registerLoader<K extends keyof T>(type: K, loader: T[K]['loader']) {\n this.loaders[type] = loader\n }\n\n _onProgress(item: SusanoLoader<unknown>) {\n this.loadCount++\n\n // const idx = this.active.indexOf(item);\n // this.active.splice(idx, 1);\n\n const progress = this.loadCount / this.loadLength\n\n this.emit('progress', {\n value: progress,\n item: item,\n susano: this,\n } satisfies ProgressEventArgs)\n\n if (progress === 1) {\n this.emit('completed', this)\n return\n }\n }\n\n start({\n onCompleted,\n onProgress,\n }: {\n onCompleted?: (susano: Susano<T>) => void\n onProgress?: (progress: { value: number; item: SusanoLoader<unknown>; susano: Susano<T> }) => void\n } = {}) {\n this.active = this.queue.splice(0, this.queue.length)\n this.loadLength = this.active.length\n this.loadCount = 0\n\n this.emit('start', this)\n\n if (onProgress) this.on('progress', onProgress)\n\n this.once('completed', () => {\n onCompleted?.(this)\n if (onProgress) this.off('progress', onProgress)\n })\n\n this.active.map((item) => {\n item.once('loaded', () => {\n this._onProgress(item)\n })\n\n item.load()\n })\n }\n}\n\nexport const susano = new Susano<{\n image: {\n type: 'image'\n loader: typeof ImageLoader\n }\n video: {\n type: 'video'\n loader: typeof VideoLoader\n }\n audio: {\n type: 'audio'\n loader: typeof AudioLoader\n }\n generic: {\n type: 'generic'\n loader: typeof GenericLoader\n }\n}>()\n\nsusano.registerLoader(ImageLoader.type, ImageLoader)\nsusano.registerLoader(VideoLoader.type, VideoLoader)\nsusano.registerLoader(AudioLoader.type, AudioLoader)\nsusano.registerLoader(GenericLoader.type, GenericLoader)\n\nexport type {\n GenericLoadFn,\n SusanoImageLoaderConfig,\n SusanoVideoLoaderConfig,\n SusanoAudioLoaderConfig,\n SusanoGenericLoaderConfig,\n GenericLoader,\n ImageLoader,\n VideoLoader,\n AudioLoader,\n}\n","import { version } from '../../package.json'\n\nexport const VERSION = version\nexport * from './core'\n"]}
1
+ {"version":3,"sources":["../package.json","../packages/core/loaders/loader.ts","../packages/core/loaders/image.ts","../packages/core/loaders/video.ts","../packages/core/loaders/audio.ts","../packages/core/loaders/generic.ts","../packages/core/core.tsx","../packages/core/index.ts"],"names":["TinyEmitter"],"mappings":"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","file":"index.js","sourcesContent":["{\n \"name\": \"@joycostudio/susano\",\n \"publishConfig\": {\n \"registry\": \"https://registry.npmjs.org\",\n \"access\": \"public\"\n },\n \"version\": \"0.1.2\",\n \"description\": \"Asset load orchestration made easy\",\n \"main\": \"dist/index.js\",\n \"module\": \"dist/index.mjs\",\n \"types\": \"dist/index.d.ts\",\n \"files\": [\n \"dist\"\n ],\n \"scripts\": {\n \"build\": \"tsup\",\n \"dev\": \"concurrently \\\"tsup --watch\\\" \\\"cd templates/basic && pnpm dev\\\"\",\n \"typecheck\": \"tsc --noEmit\",\n \"version:package\": \"pnpm changeset version\",\n \"release\": \"pnpm build && pnpm changeset publish\",\n \"lint\": \"eslint -c ./eslint.config.mjs . --fix --no-cache\"\n },\n \"packageManager\": \"pnpm@10.29.2\",\n \"author\": \"@joycostudio\",\n \"license\": \"ISC\",\n \"devDependencies\": {\n \"@changesets/cli\": \"^2.27.11\",\n \"@eslint/js\": \"^9.18.0\",\n \"@types/node\": \"^20.11.24\",\n \"@types/react\": \"^18.2.61\",\n \"@typescript-eslint/eslint-plugin\": \"^8.21.0\",\n \"@typescript-eslint/parser\": \"^8.21.0\",\n \"concurrently\": \"^9.1.2\",\n \"eslint\": \"^9.18.0\",\n \"eslint-config-prettier\": \"^10.0.1\",\n \"eslint-plugin-prettier\": \"^5.2.3\",\n \"eslint-plugin-react\": \"^7.37.4\",\n \"eslint-plugin-react-compiler\": \"19.0.0-beta-decd7b8-20250118\",\n \"globals\": \"^15.14.0\",\n \"prettier\": \"^3.4.2\",\n \"react\": \"^18.2.0\",\n \"tsup\": \"^8.0.2\",\n \"typescript\": \"^5.7.3\",\n \"typescript-eslint\": \"^8.21.0\"\n },\n \"peerDependencies\": {\n \"react\": \">=16.8.0\"\n },\n \"dependencies\": {\n \"tiny-emitter\": \"^2.1.0\"\n }\n}","import { TinyEmitter } from 'tiny-emitter'\n\nexport type SusanoLoaderConfig<T> = {\n onLoaded?: (loader: SusanoLoader<T>) => void\n onProgress?: (loader: SusanoLoader<T>) => void\n}\n\nexport class SusanoLoader<T> extends TinyEmitter implements ISusanoLoader<T> {\n public url: string\n public loaded: boolean\n public content: T\n public config: SusanoLoaderConfig<T>\n public weight: number\n public progress: number\n public promise!: Promise<T>\n private _resolve!: (value: T) => void\n private _reject!: (error: unknown) => void\n\n constructor(url: string, _cnfg: SusanoLoaderConfig<T> = {}) {\n super()\n this.url = url\n this.loaded = false\n this.content = null as unknown as T\n this.config = _cnfg\n this.weight = 1\n this.progress = 0\n\n this._resetPromise()\n }\n\n load(): Promise<T> {\n throw new Error('Method not implemented')\n }\n\n _onLoaded() {\n this.loaded = true\n this.progress = 1\n this._resolve(this.content)\n this.emit('loaded', this)\n this.config.onLoaded?.(this)\n }\n\n _onError(error: unknown) {\n this._reject(error)\n this.progress = 0\n this._resetPromise()\n this.emit('error', error)\n }\n\n private _resetPromise() {\n this.promise = new Promise<T>((resolve, reject) => {\n this._resolve = resolve\n this._reject = reject\n })\n }\n\n _onProgress(value: number) {\n this.progress = value\n this.emit('progress', this)\n this.config.onProgress?.(this)\n }\n\n /**\n * This is ment to be used as a way to attach to master loader events\n */\n _appendConfig(cnfg: SusanoLoaderConfig<T>) {\n const _onLoaded = this.config.onLoaded\n this.config.onLoaded = (loader) => {\n _onLoaded?.(loader)\n cnfg.onLoaded?.(loader)\n }\n\n const _onProgress = this.config.onProgress\n\n this.config.onProgress = (loader) => {\n _onProgress?.(loader)\n cnfg.onProgress?.(loader)\n }\n }\n}\n\nexport interface ISusanoLoader<T> {\n load: () => Promise<T>\n}\n","import { ISusanoLoader, SusanoLoaderConfig, SusanoLoader } from './loader'\n\nexport type SusanoImageLoaderConfig = SusanoLoaderConfig<HTMLImageElement> & {\n srcSet?: string\n sizes?: string\n}\n\nexport class ImageLoader extends SusanoLoader<HTMLImageElement> implements ISusanoLoader<HTMLImageElement> {\n public static type = 'image' as const\n public srcSet?: string\n public sizes?: string\n\n constructor(url: string, cnfg: SusanoImageLoaderConfig = {}) {\n super(url, cnfg)\n this.content = new Image()\n this.srcSet = cnfg.srcSet\n this.sizes = cnfg.sizes\n }\n\n load(): Promise<HTMLImageElement> {\n if (this.loaded) { this._onLoaded(); return this.promise }\n\n if (this.srcSet) this.content.srcset = this.srcSet\n if (this.sizes) this.content.sizes = this.sizes\n this.content.src = this.url\n\n this.content.onload = () => this._onLoaded()\n this.content.onerror = (e) => this._onError(e)\n\n return this.promise\n }\n}\n","import { ISusanoLoader, SusanoLoaderConfig, SusanoLoader } from './loader'\n\ntype LoadEvent = 'canplay' | 'canplaythrough'\n\nexport type SusanoVideoLoaderConfig = SusanoLoaderConfig<HTMLVideoElement> & {\n video?: HTMLVideoElement\n loadEvent?: LoadEvent\n}\n\nexport class VideoLoader extends SusanoLoader<HTMLVideoElement> implements ISusanoLoader<HTMLVideoElement> {\n public static type = 'video' as const\n public loadEvent: LoadEvent\n\n constructor(url: string, cnfg: SusanoVideoLoaderConfig = {}) {\n super(url, cnfg)\n this.content = cnfg.video || document.createElement('video')\n this.loadEvent = cnfg.loadEvent || 'canplay'\n }\n\n load(): Promise<HTMLVideoElement> {\n if (this.loaded) { this._onLoaded(); return this.promise }\n\n const el = this.content\n el.src = this.url\n el.addEventListener(this.loadEvent, () => this._onLoaded(), { once: true })\n el.addEventListener('error', (e) => this._onError(e), { once: true })\n\n return this.promise\n }\n}\n","import { ISusanoLoader, SusanoLoaderConfig, SusanoLoader } from './loader'\n\ntype LoadEvent = 'canplay' | 'canplaythrough'\n\nexport type SusanoAudioLoaderConfig = SusanoLoaderConfig<HTMLAudioElement> & {\n audio?: HTMLAudioElement\n loadEvent?: LoadEvent\n}\n\nexport class AudioLoader extends SusanoLoader<HTMLAudioElement> implements ISusanoLoader<HTMLAudioElement> {\n public static type = 'audio' as const\n public loadEvent: LoadEvent\n\n constructor(url: string, cnfg: SusanoAudioLoaderConfig = {}) {\n super(url, cnfg)\n this.content = cnfg.audio || document.createElement('audio')\n this.loadEvent = cnfg.loadEvent || 'canplay'\n }\n\n load(): Promise<HTMLAudioElement> {\n if (this.loaded) { this._onLoaded(); return this.promise }\n\n const el = this.content\n el.src = this.url\n el.addEventListener(this.loadEvent, () => this._onLoaded(), { once: true })\n el.addEventListener('error', (e) => this._onError(e), { once: true })\n\n return this.promise\n }\n}\n","import { SusanoLoader, SusanoLoaderConfig } from './loader'\n\nexport type GenericLoadFn = (config: {\n url: string\n done: (generic: any) => void\n error: (error: Error) => void\n progress: (progress: number) => void\n}) => void\n\nexport type SusanoGenericLoaderConfig = SusanoLoaderConfig<any> & {\n loadFn: GenericLoadFn\n}\n\nexport class GenericLoader extends SusanoLoader<any> {\n public static type = 'generic' as const\n public loadFn: GenericLoadFn\n\n constructor(url: string, cnfg: SusanoGenericLoaderConfig) {\n super(url, cnfg)\n this.loadFn = cnfg.loadFn\n }\n\n load(): Promise<any> {\n if (!this.loadFn) { this._onError(new Error('No load function provided')); return this.promise }\n if (this.loaded) { this._onLoaded(); return this.promise }\n\n this.loadFn({\n url: this.url,\n done: (generic: any) => { this.content = generic; this._onLoaded() },\n error: (err) => this._onError(err),\n /* 0 to 1 */\n progress: (value: number) => this._onProgress(value),\n })\n\n return this.promise\n }\n}\n","import { TinyEmitter } from 'tiny-emitter'\nimport { SusanoLoader } from './loaders/loader'\nimport { ImageLoader } from './loaders/image'\nimport { VideoLoader } from './loaders/video'\nimport { AudioLoader } from './loaders/audio'\nimport { GenericLoader } from './loaders/generic'\n\nexport type LoaderTypes = {\n [K: string]: {\n type: typeof K\n loader: typeof SusanoLoader<any>\n }\n}\n\nexport type LoaderMap<T extends LoaderTypes> = {\n [K in keyof T]: T[K]['loader']\n}\n\nexport type ProgressEventArgs = {\n value: number\n item: SusanoLoader<unknown>\n susano: Susano<any>\n}\n\n/**\n * Main loader class that manages loading of different asset types\n * @template T Type definition for the loaders to be used, extending LoaderTypes\n * @extends TinyEmitter\n */\nexport class Susano<T extends LoaderTypes> extends TinyEmitter {\n private loaders: LoaderMap<T> = {} as LoaderMap<T>\n public queue: InstanceType<T[keyof T]['loader']>[] = []\n public active: InstanceType<T[keyof T]['loader']>[] = []\n public items: Map<string, InstanceType<T[keyof T]['loader']>> = new Map()\n public loadCount: number = 0\n public loadLength: number = 0\n\n constructor() {\n super()\n }\n\n add<K extends keyof T>(\n url: string,\n cnfg: {\n type: K\n loaderArgs?: ConstructorParameters<T[K]['loader']>[1]\n }\n ): InstanceType<T[K]['loader']> {\n const Loader = this.loaders[cnfg.type]\n\n if (!Loader) throw new Error(`Loader for type ${String(cnfg.type)} not found`)\n\n let item = this.items.get(url)\n\n if (!item) {\n item = new Loader(url, cnfg.loaderArgs) as InstanceType<T[K]['loader']>\n this.items.set(url, item)\n } else if (cnfg.loaderArgs) {\n item._appendConfig(cnfg.loaderArgs)\n }\n\n this.queue.push(item)\n\n return item\n }\n\n load<K extends keyof T>(\n url: string,\n cnfg: {\n type: K\n loaderArgs?: ConstructorParameters<T[K]['loader']>[1]\n }\n ) {\n const Loader = this.loaders[cnfg.type]\n if (!Loader) throw new Error(`Loader for type ${String(cnfg.type)} not found`)\n\n let item = this.items.get(url)\n\n if (!item) {\n item = new Loader(url, cnfg.loaderArgs) as InstanceType<T[K]['loader']>\n this.items.set(url, item)\n } else if (cnfg.loaderArgs) {\n item._appendConfig(cnfg.loaderArgs)\n }\n\n item.load()\n\n return item\n }\n\n registerLoader<K extends keyof T>(type: K, loader: T[K]['loader']) {\n this.loaders[type] = loader\n }\n\n _onProgress(item: SusanoLoader<unknown>) {\n this.loadCount++\n\n // const idx = this.active.indexOf(item);\n // this.active.splice(idx, 1);\n\n const progress = this.loadCount / this.loadLength\n\n this.emit('progress', {\n value: progress,\n item: item,\n susano: this,\n } satisfies ProgressEventArgs)\n\n if (progress === 1) {\n this.emit('completed', this)\n return\n }\n }\n\n start({\n onCompleted,\n onProgress,\n }: {\n onCompleted?: (susano: Susano<T>) => void\n onProgress?: (progress: { value: number; item: SusanoLoader<unknown>; susano: Susano<T> }) => void\n } = {}) {\n this.active = this.queue.splice(0, this.queue.length)\n this.loadLength = this.active.length\n this.loadCount = 0\n\n this.emit('start', this)\n\n if (onProgress) this.on('progress', onProgress)\n\n this.once('completed', () => {\n onCompleted?.(this)\n if (onProgress) this.off('progress', onProgress)\n })\n\n this.active.map((item) => {\n item.once('loaded', () => {\n this._onProgress(item)\n })\n\n item.load()\n })\n }\n}\n\nexport const susano = new Susano<{\n image: {\n type: 'image'\n loader: typeof ImageLoader\n }\n video: {\n type: 'video'\n loader: typeof VideoLoader\n }\n audio: {\n type: 'audio'\n loader: typeof AudioLoader\n }\n generic: {\n type: 'generic'\n loader: typeof GenericLoader\n }\n}>()\n\nsusano.registerLoader(ImageLoader.type, ImageLoader)\nsusano.registerLoader(VideoLoader.type, VideoLoader)\nsusano.registerLoader(AudioLoader.type, AudioLoader)\nsusano.registerLoader(GenericLoader.type, GenericLoader)\n\nexport * from './loaders/loader'\nexport * from './loaders/image'\nexport * from './loaders/video'\nexport * from './loaders/audio'\nexport * from './loaders/generic'\n","import { version } from '../../package.json'\n\nexport const VERSION = version\nexport * from './core'\n"]}
package/dist/index.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import { TinyEmitter } from 'tiny-emitter';
2
2
 
3
3
  // package.json
4
- var version = "0.1.0";
4
+ var version = "0.1.2";
5
5
  var SusanoLoader = class extends TinyEmitter {
6
6
  constructor(url, _cnfg = {}) {
7
7
  super();
@@ -11,6 +11,7 @@ var SusanoLoader = class extends TinyEmitter {
11
11
  this.config = _cnfg;
12
12
  this.weight = 1;
13
13
  this.progress = 0;
14
+ this._resetPromise();
14
15
  }
15
16
  load() {
16
17
  throw new Error("Method not implemented");
@@ -18,9 +19,22 @@ var SusanoLoader = class extends TinyEmitter {
18
19
  _onLoaded() {
19
20
  this.loaded = true;
20
21
  this.progress = 1;
22
+ this._resolve(this.content);
21
23
  this.emit("loaded", this);
22
24
  this.config.onLoaded?.(this);
23
25
  }
26
+ _onError(error) {
27
+ this._reject(error);
28
+ this.progress = 0;
29
+ this._resetPromise();
30
+ this.emit("error", error);
31
+ }
32
+ _resetPromise() {
33
+ this.promise = new Promise((resolve, reject) => {
34
+ this._resolve = resolve;
35
+ this._reject = reject;
36
+ });
37
+ }
24
38
  _onProgress(value) {
25
39
  this.progress = value;
26
40
  this.emit("progress", this);
@@ -52,21 +66,16 @@ var ImageLoader = class extends SusanoLoader {
52
66
  this.sizes = cnfg.sizes;
53
67
  }
54
68
  load() {
55
- return new Promise((resolve, reject) => {
56
- if (this.loaded) {
57
- this._onLoaded.call(this);
58
- resolve(this.content);
59
- return;
60
- }
61
- if (this.srcSet) this.content.srcset = this.srcSet;
62
- if (this.sizes) this.content.sizes = this.sizes;
63
- this.content.src = this.url;
64
- this.content.onload = () => {
65
- this._onLoaded.call(this);
66
- resolve(this.content);
67
- };
68
- this.content.onerror = (e) => reject(e);
69
- });
69
+ if (this.loaded) {
70
+ this._onLoaded();
71
+ return this.promise;
72
+ }
73
+ if (this.srcSet) this.content.srcset = this.srcSet;
74
+ if (this.sizes) this.content.sizes = this.sizes;
75
+ this.content.src = this.url;
76
+ this.content.onload = () => this._onLoaded();
77
+ this.content.onerror = (e) => this._onError(e);
78
+ return this.promise;
70
79
  }
71
80
  };
72
81
  ImageLoader.type = "image";
@@ -79,20 +88,15 @@ var VideoLoader = class extends SusanoLoader {
79
88
  this.loadEvent = cnfg.loadEvent || "canplay";
80
89
  }
81
90
  load() {
82
- return new Promise((resolve, reject) => {
83
- const video = this.content;
84
- if (this.loaded) {
85
- this._onLoaded.call(this);
86
- resolve(this.content);
87
- return;
88
- }
89
- video.src = this.url;
90
- video.addEventListener(this.loadEvent, () => {
91
- this._onLoaded.call(this);
92
- resolve(this.content);
93
- });
94
- video.addEventListener("error", (e) => reject(e));
95
- });
91
+ if (this.loaded) {
92
+ this._onLoaded();
93
+ return this.promise;
94
+ }
95
+ const el = this.content;
96
+ el.src = this.url;
97
+ el.addEventListener(this.loadEvent, () => this._onLoaded(), { once: true });
98
+ el.addEventListener("error", (e) => this._onError(e), { once: true });
99
+ return this.promise;
96
100
  }
97
101
  };
98
102
  VideoLoader.type = "video";
@@ -105,20 +109,15 @@ var AudioLoader = class extends SusanoLoader {
105
109
  this.loadEvent = cnfg.loadEvent || "canplay";
106
110
  }
107
111
  load() {
108
- return new Promise((resolve, reject) => {
109
- const audio = this.content;
110
- if (this.loaded) {
111
- this._onLoaded.call(this);
112
- resolve(this.content);
113
- return;
114
- }
115
- audio.src = this.url;
116
- audio.addEventListener(this.loadEvent, () => {
117
- this._onLoaded.call(this);
118
- resolve(this.content);
119
- });
120
- audio.addEventListener("error", (e) => reject(e));
121
- });
112
+ if (this.loaded) {
113
+ this._onLoaded();
114
+ return this.promise;
115
+ }
116
+ const el = this.content;
117
+ el.src = this.url;
118
+ el.addEventListener(this.loadEvent, () => this._onLoaded(), { once: true });
119
+ el.addEventListener("error", (e) => this._onError(e), { once: true });
120
+ return this.promise;
122
121
  }
123
122
  };
124
123
  AudioLoader.type = "audio";
@@ -130,30 +129,25 @@ var GenericLoader = class extends SusanoLoader {
130
129
  this.loadFn = cnfg.loadFn;
131
130
  }
132
131
  load() {
133
- return new Promise((resolve, reject) => {
134
- if (!this.loadFn) {
135
- reject(new Error("No load function provided"));
136
- return;
137
- }
138
- if (this.loaded) {
139
- this._onLoaded.call(this);
140
- resolve(this.content);
141
- return;
142
- }
143
- this.loadFn({
144
- url: this.url,
145
- done: (generic) => {
146
- this.content = generic;
147
- this._onLoaded.call(this);
148
- resolve(generic);
149
- },
150
- error: reject,
151
- /* 0 to 1 */
152
- progress: (value) => {
153
- this._onProgress.call(this, value);
154
- }
155
- });
132
+ if (!this.loadFn) {
133
+ this._onError(new Error("No load function provided"));
134
+ return this.promise;
135
+ }
136
+ if (this.loaded) {
137
+ this._onLoaded();
138
+ return this.promise;
139
+ }
140
+ this.loadFn({
141
+ url: this.url,
142
+ done: (generic) => {
143
+ this.content = generic;
144
+ this._onLoaded();
145
+ },
146
+ error: (err) => this._onError(err),
147
+ /* 0 to 1 */
148
+ progress: (value) => this._onProgress(value)
156
149
  });
150
+ return this.promise;
157
151
  }
158
152
  };
159
153
  GenericLoader.type = "generic";
@@ -241,6 +235,6 @@ susano.registerLoader(GenericLoader.type, GenericLoader);
241
235
  // packages/core/index.ts
242
236
  var VERSION = version;
243
237
 
244
- export { Susano, VERSION, susano };
238
+ export { AudioLoader, GenericLoader, ImageLoader, Susano, SusanoLoader, VERSION, VideoLoader, susano };
245
239
  //# sourceMappingURL=index.mjs.map
246
240
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../package.json","../packages/core/loaders/loader.ts","../packages/core/loaders/image.ts","../packages/core/loaders/video.ts","../packages/core/loaders/audio.ts","../packages/core/loaders/generic.ts","../packages/core/core.tsx","../packages/core/index.ts"],"names":["TinyEmitter"],"mappings":";;;AAME,IAAA,OAAA,GAAW,OAAA;ACCN,IAAM,YAAA,GAAN,cAA8B,WAAA,CAAwC;AAAA,EAQ3E,WAAA,CAAY,GAAA,EAAa,KAAA,GAA+B,EAAC,EAAG;AAC1D,IAAA,KAAA,EAAM;AACN,IAAA,IAAA,CAAK,GAAA,GAAM,GAAA;AACX,IAAA,IAAA,CAAK,MAAA,GAAS,KAAA;AACd,IAAA,IAAA,CAAK,OAAA,GAAU,IAAA;AACf,IAAA,IAAA,CAAK,MAAA,GAAS,KAAA;AACd,IAAA,IAAA,CAAK,MAAA,GAAS,CAAA;AACd,IAAA,IAAA,CAAK,QAAA,GAAW,CAAA;AAAA,EAClB;AAAA,EAEA,IAAA,GAAmB;AACjB,IAAA,MAAM,IAAI,MAAM,wBAAwB,CAAA;AAAA,EAC1C;AAAA,EAEA,SAAA,GAAY;AACV,IAAA,IAAA,CAAK,MAAA,GAAS,IAAA;AACd,IAAA,IAAA,CAAK,QAAA,GAAW,CAAA;AAChB,IAAA,IAAA,CAAK,IAAA,CAAK,UAAU,IAAI,CAAA;AACxB,IAAA,IAAA,CAAK,MAAA,CAAO,WAAW,IAAI,CAAA;AAAA,EAC7B;AAAA,EAEA,YAAY,KAAA,EAAe;AACzB,IAAA,IAAA,CAAK,QAAA,GAAW,KAAA;AAChB,IAAA,IAAA,CAAK,IAAA,CAAK,YAAY,IAAI,CAAA;AAC1B,IAAA,IAAA,CAAK,MAAA,CAAO,aAAa,IAAI,CAAA;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA,EAKA,cAAc,IAAA,EAA6B;AACzC,IAAA,MAAM,SAAA,GAAY,KAAK,MAAA,CAAO,QAAA;AAC9B,IAAA,IAAA,CAAK,MAAA,CAAO,QAAA,GAAW,CAAC,MAAA,KAAW;AACjC,MAAA,SAAA,GAAY,MAAM,CAAA;AAClB,MAAA,IAAA,CAAK,WAAW,MAAM,CAAA;AAAA,IACxB,CAAA;AAEA,IAAA,MAAM,WAAA,GAAc,KAAK,MAAA,CAAO,UAAA;AAEhC,IAAA,IAAA,CAAK,MAAA,CAAO,UAAA,GAAa,CAAC,MAAA,KAAW;AACnC,MAAA,WAAA,GAAc,MAAM,CAAA;AACpB,MAAA,IAAA,CAAK,aAAa,MAAM,CAAA;AAAA,IAC1B,CAAA;AAAA,EACF;AACF,CAAA;;;ACpDO,IAAM,WAAA,GAAN,cAA0B,YAAA,CAA0E;AAAA,EAKzG,WAAA,CAAY,GAAA,EAAa,IAAA,GAAgC,EAAC,EAAG;AAC3D,IAAA,KAAA,CAAM,KAAK,IAAI,CAAA;AACf,IAAA,IAAA,CAAK,OAAA,GAAU,IAAI,KAAA,EAAM;AACzB,IAAA,IAAA,CAAK,SAAS,IAAA,CAAK,MAAA;AACnB,IAAA,IAAA,CAAK,QAAQ,IAAA,CAAK,KAAA;AAAA,EACpB;AAAA,EAEA,IAAA,GAAkC;AAChC,IAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,OAAA,EAAS,MAAA,KAAW;AACtC,MAAA,IAAI,KAAK,MAAA,EAAQ;AACf,QAAA,IAAA,CAAK,SAAA,CAAU,KAAK,IAAI,CAAA;AACxB,QAAA,OAAA,CAAQ,KAAK,OAAO,CAAA;AACpB,QAAA;AAAA,MACF;AAEA,MAAA,IAAI,IAAA,CAAK,MAAA,EAAQ,IAAA,CAAK,OAAA,CAAQ,SAAS,IAAA,CAAK,MAAA;AAC5C,MAAA,IAAI,IAAA,CAAK,KAAA,EAAO,IAAA,CAAK,OAAA,CAAQ,QAAQ,IAAA,CAAK,KAAA;AAC1C,MAAA,IAAA,CAAK,OAAA,CAAQ,MAAM,IAAA,CAAK,GAAA;AAExB,MAAA,IAAA,CAAK,OAAA,CAAQ,SAAS,MAAM;AAC1B,QAAA,IAAA,CAAK,SAAA,CAAU,KAAK,IAAI,CAAA;AACxB,QAAA,OAAA,CAAQ,KAAK,OAAO,CAAA;AAAA,MACtB,CAAA;AAEA,MAAA,IAAA,CAAK,OAAA,CAAQ,OAAA,GAAU,CAAC,CAAA,KAAM,OAAO,CAAC,CAAA;AAAA,IACxC,CAAC,CAAA;AAAA,EACH;AACF,CAAA;AAhCa,WAAA,CACG,IAAA,GAAO,OAAA;;;ACChB,IAAM,WAAA,GAAN,cAA0B,YAAA,CAA0E;AAAA,EAIzG,WAAA,CAAY,GAAA,EAAa,IAAA,GAAgC,EAAC,EAAG;AAC3D,IAAA,KAAA,CAAM,KAAK,IAAI,CAAA;AACf,IAAA,IAAA,CAAK,OAAA,GAAU,IAAA,CAAK,KAAA,IAAS,QAAA,CAAS,cAAc,OAAO,CAAA;AAC3D,IAAA,IAAA,CAAK,SAAA,GAAY,KAAK,SAAA,IAAa,SAAA;AAAA,EACrC;AAAA,EAEA,IAAA,GAAkC;AAChC,IAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,OAAA,EAAS,MAAA,KAAW;AACtC,MAAA,MAAM,QAAQ,IAAA,CAAK,OAAA;AAEnB,MAAA,IAAI,KAAK,MAAA,EAAQ;AACf,QAAA,IAAA,CAAK,SAAA,CAAU,KAAK,IAAI,CAAA;AACxB,QAAA,OAAA,CAAQ,KAAK,OAAO,CAAA;AACpB,QAAA;AAAA,MACF;AAEA,MAAA,KAAA,CAAM,MAAM,IAAA,CAAK,GAAA;AAEjB,MAAA,KAAA,CAAM,gBAAA,CAAiB,IAAA,CAAK,SAAA,EAAW,MAAM;AAC3C,QAAA,IAAA,CAAK,SAAA,CAAU,KAAK,IAAI,CAAA;AACxB,QAAA,OAAA,CAAQ,KAAK,OAAO,CAAA;AAAA,MACtB,CAAC,CAAA;AAED,MAAA,KAAA,CAAM,iBAAiB,OAAA,EAAS,CAAC,CAAA,KAAM,MAAA,CAAO,CAAC,CAAC,CAAA;AAAA,IAClD,CAAC,CAAA;AAAA,EACH;AACF,CAAA;AA9Ba,WAAA,CACG,IAAA,GAAO,OAAA;;;ACDhB,IAAM,WAAA,GAAN,cAA0B,YAAA,CAA0E;AAAA,EAIzG,WAAA,CAAY,GAAA,EAAa,IAAA,GAAgC,EAAC,EAAG;AAC3D,IAAA,KAAA,CAAM,KAAK,IAAI,CAAA;AACf,IAAA,IAAA,CAAK,OAAA,GAAU,IAAA,CAAK,KAAA,IAAS,QAAA,CAAS,cAAc,OAAO,CAAA;AAC3D,IAAA,IAAA,CAAK,SAAA,GAAY,KAAK,SAAA,IAAa,SAAA;AAAA,EACrC;AAAA,EAEA,IAAA,GAAkC;AAChC,IAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,OAAA,EAAS,MAAA,KAAW;AACtC,MAAA,MAAM,QAAQ,IAAA,CAAK,OAAA;AAEnB,MAAA,IAAI,KAAK,MAAA,EAAQ;AACf,QAAA,IAAA,CAAK,SAAA,CAAU,KAAK,IAAI,CAAA;AACxB,QAAA,OAAA,CAAQ,KAAK,OAAO,CAAA;AACpB,QAAA;AAAA,MACF;AAEA,MAAA,KAAA,CAAM,MAAM,IAAA,CAAK,GAAA;AAEjB,MAAA,KAAA,CAAM,gBAAA,CAAiB,IAAA,CAAK,SAAA,EAAW,MAAM;AAC3C,QAAA,IAAA,CAAK,SAAA,CAAU,KAAK,IAAI,CAAA;AACxB,QAAA,OAAA,CAAQ,KAAK,OAAO,CAAA;AAAA,MACtB,CAAC,CAAA;AAED,MAAA,KAAA,CAAM,iBAAiB,OAAA,EAAS,CAAC,CAAA,KAAM,MAAA,CAAO,CAAC,CAAC,CAAA;AAAA,IAClD,CAAC,CAAA;AAAA,EACH;AACF,CAAA;AA9Ba,WAAA,CACG,IAAA,GAAO,OAAA;;;ACGhB,IAAM,aAAA,GAAN,cAA4B,YAAA,CAAkB;AAAA,EAInD,WAAA,CAAY,KAAa,IAAA,EAAiC;AACxD,IAAA,KAAA,CAAM,KAAK,IAAI,CAAA;AACf,IAAA,IAAA,CAAK,SAAS,IAAA,CAAK,MAAA;AAAA,EACrB;AAAA,EAEA,IAAA,GAAqB;AACnB,IAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,OAAA,EAAS,MAAA,KAAW;AACtC,MAAA,IAAI,CAAC,KAAK,MAAA,EAAQ;AAChB,QAAA,MAAA,CAAO,IAAI,KAAA,CAAM,2BAA2B,CAAC,CAAA;AAC7C,QAAA;AAAA,MACF;AAEA,MAAA,IAAI,KAAK,MAAA,EAAQ;AACf,QAAA,IAAA,CAAK,SAAA,CAAU,KAAK,IAAI,CAAA;AACxB,QAAA,OAAA,CAAQ,KAAK,OAAO,CAAA;AACpB,QAAA;AAAA,MACF;AAEA,MAAA,IAAA,CAAK,MAAA,CAAO;AAAA,QACV,KAAK,IAAA,CAAK,GAAA;AAAA,QACV,IAAA,EAAM,CAAC,OAAA,KAAiB;AACtB,UAAA,IAAA,CAAK,OAAA,GAAU,OAAA;AACf,UAAA,IAAA,CAAK,SAAA,CAAU,KAAK,IAAI,CAAA;AACxB,UAAA,OAAA,CAAQ,OAAO,CAAA;AAAA,QACjB,CAAA;AAAA,QACA,KAAA,EAAO,MAAA;AAAA;AAAA,QAEP,QAAA,EAAU,CAAC,KAAA,KAAkB;AAC3B,UAAA,IAAA,CAAK,WAAA,CAAY,IAAA,CAAK,IAAA,EAAM,KAAK,CAAA;AAAA,QACnC;AAAA,OACD,CAAA;AAAA,IACH,CAAC,CAAA;AAAA,EACH;AACF,CAAA;AArCa,aAAA,CACG,IAAA,GAAO,SAAA;;;ACehB,IAAM,MAAA,GAAN,cAA4CA,WAAAA,CAAY;AAAA,EAQ7D,WAAA,GAAc;AACZ,IAAA,KAAA,EAAM;AARR,IAAA,IAAA,CAAQ,UAAwB,EAAC;AACjC,IAAA,IAAA,CAAO,QAA8C,EAAC;AACtD,IAAA,IAAA,CAAO,SAA+C,EAAC;AACvD,IAAA,IAAA,CAAO,KAAA,uBAA6D,GAAA,EAAI;AACxE,IAAA,IAAA,CAAO,SAAA,GAAoB,CAAA;AAC3B,IAAA,IAAA,CAAO,UAAA,GAAqB,CAAA;AAAA,EAI5B;AAAA,EAEA,GAAA,CACE,KACA,IAAA,EAI8B;AAC9B,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,OAAA,CAAQ,IAAA,CAAK,IAAI,CAAA;AAErC,IAAA,IAAI,CAAC,MAAA,EAAQ,MAAM,IAAI,KAAA,CAAM,mBAAmB,MAAA,CAAO,IAAA,CAAK,IAAI,CAAC,CAAA,UAAA,CAAY,CAAA;AAE7E,IAAA,IAAI,IAAA,GAAO,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,GAAG,CAAA;AAE7B,IAAA,IAAI,CAAC,IAAA,EAAM;AACT,MAAA,IAAA,GAAO,IAAI,MAAA,CAAO,GAAA,EAAK,IAAA,CAAK,UAAU,CAAA;AACtC,MAAA,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,GAAA,EAAK,IAAI,CAAA;AAAA,IAC1B,CAAA,MAAA,IAAW,KAAK,UAAA,EAAY;AAC1B,MAAA,IAAA,CAAK,aAAA,CAAc,KAAK,UAAU,CAAA;AAAA,IACpC;AAEA,IAAA,IAAA,CAAK,KAAA,CAAM,KAAK,IAAI,CAAA;AAEpB,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEA,IAAA,CACE,KACA,IAAA,EAIA;AACA,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,OAAA,CAAQ,IAAA,CAAK,IAAI,CAAA;AACrC,IAAA,IAAI,CAAC,MAAA,EAAQ,MAAM,IAAI,KAAA,CAAM,mBAAmB,MAAA,CAAO,IAAA,CAAK,IAAI,CAAC,CAAA,UAAA,CAAY,CAAA;AAE7E,IAAA,IAAI,IAAA,GAAO,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,GAAG,CAAA;AAE7B,IAAA,IAAI,CAAC,IAAA,EAAM;AACT,MAAA,IAAA,GAAO,IAAI,MAAA,CAAO,GAAA,EAAK,IAAA,CAAK,UAAU,CAAA;AACtC,MAAA,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,GAAA,EAAK,IAAI,CAAA;AAAA,IAC1B,CAAA,MAAA,IAAW,KAAK,UAAA,EAAY;AAC1B,MAAA,IAAA,CAAK,aAAA,CAAc,KAAK,UAAU,CAAA;AAAA,IACpC;AAEA,IAAA,IAAA,CAAK,IAAA,EAAK;AAEV,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEA,cAAA,CAAkC,MAAS,MAAA,EAAwB;AACjE,IAAA,IAAA,CAAK,OAAA,CAAQ,IAAI,CAAA,GAAI,MAAA;AAAA,EACvB;AAAA,EAEA,YAAY,IAAA,EAA6B;AACvC,IAAA,IAAA,CAAK,SAAA,EAAA;AAKL,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,SAAA,GAAY,IAAA,CAAK,UAAA;AAEvC,IAAA,IAAA,CAAK,KAAK,UAAA,EAAY;AAAA,MACpB,KAAA,EAAO,QAAA;AAAA,MACP,IAAA;AAAA,MACA,MAAA,EAAQ;AAAA,KACmB,CAAA;AAE7B,IAAA,IAAI,aAAa,CAAA,EAAG;AAClB,MAAA,IAAA,CAAK,IAAA,CAAK,aAAa,IAAI,CAAA;AAC3B,MAAA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,KAAA,CAAM;AAAA,IACJ,WAAA;AAAA,IACA;AAAA,GACF,GAGI,EAAC,EAAG;AACN,IAAA,IAAA,CAAK,SAAS,IAAA,CAAK,KAAA,CAAM,OAAO,CAAA,EAAG,IAAA,CAAK,MAAM,MAAM,CAAA;AACpD,IAAA,IAAA,CAAK,UAAA,GAAa,KAAK,MAAA,CAAO,MAAA;AAC9B,IAAA,IAAA,CAAK,SAAA,GAAY,CAAA;AAEjB,IAAA,IAAA,CAAK,IAAA,CAAK,SAAS,IAAI,CAAA;AAEvB,IAAA,IAAI,UAAA,EAAY,IAAA,CAAK,EAAA,CAAG,UAAA,EAAY,UAAU,CAAA;AAE9C,IAAA,IAAA,CAAK,IAAA,CAAK,aAAa,MAAM;AAC3B,MAAA,WAAA,GAAc,IAAI,CAAA;AAClB,MAAA,IAAI,UAAA,EAAY,IAAA,CAAK,GAAA,CAAI,UAAA,EAAY,UAAU,CAAA;AAAA,IACjD,CAAC,CAAA;AAED,IAAA,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,CAAC,IAAA,KAAS;AACxB,MAAA,IAAA,CAAK,IAAA,CAAK,UAAU,MAAM;AACxB,QAAA,IAAA,CAAK,YAAY,IAAI,CAAA;AAAA,MACvB,CAAC,CAAA;AAED,MAAA,IAAA,CAAK,IAAA,EAAK;AAAA,IACZ,CAAC,CAAA;AAAA,EACH;AACF;AAEO,IAAM,MAAA,GAAS,IAAI,MAAA;AAmB1B,MAAA,CAAO,cAAA,CAAe,WAAA,CAAY,IAAA,EAAM,WAAW,CAAA;AACnD,MAAA,CAAO,cAAA,CAAe,WAAA,CAAY,IAAA,EAAM,WAAW,CAAA;AACnD,MAAA,CAAO,cAAA,CAAe,WAAA,CAAY,IAAA,EAAM,WAAW,CAAA;AACnD,MAAA,CAAO,cAAA,CAAe,aAAA,CAAc,IAAA,EAAM,aAAa,CAAA;;;ACpKhD,IAAM,OAAA,GAAU","file":"index.mjs","sourcesContent":["{\n \"name\": \"@joycostudio/susano\",\n \"publishConfig\": {\n \"registry\": \"https://registry.npmjs.org\",\n \"access\": \"public\"\n },\n \"version\": \"0.1.0\",\n \"description\": \"Asset load orchestration made easy\",\n \"main\": \"dist/index.js\",\n \"module\": \"dist/index.mjs\",\n \"types\": \"dist/index.d.ts\",\n \"files\": [\n \"dist\"\n ],\n \"scripts\": {\n \"build\": \"tsup\",\n \"dev\": \"concurrently \\\"tsup --watch\\\" \\\"cd templates/basic && pnpm dev\\\"\",\n \"typecheck\": \"tsc --noEmit\",\n \"version:package\": \"pnpm changeset version\",\n \"release\": \"pnpm build && pnpm changeset publish\",\n \"lint\": \"eslint -c ./eslint.config.mjs . --fix --no-cache\"\n },\n \"packageManager\": \"pnpm@10.29.2\",\n \"author\": \"@joycostudio\",\n \"license\": \"ISC\",\n \"devDependencies\": {\n \"@changesets/cli\": \"^2.27.11\",\n \"@eslint/js\": \"^9.18.0\",\n \"@types/node\": \"^20.11.24\",\n \"@types/react\": \"^18.2.61\",\n \"@typescript-eslint/eslint-plugin\": \"^8.21.0\",\n \"@typescript-eslint/parser\": \"^8.21.0\",\n \"concurrently\": \"^9.1.2\",\n \"eslint\": \"^9.18.0\",\n \"eslint-config-prettier\": \"^10.0.1\",\n \"eslint-plugin-prettier\": \"^5.2.3\",\n \"eslint-plugin-react\": \"^7.37.4\",\n \"eslint-plugin-react-compiler\": \"19.0.0-beta-decd7b8-20250118\",\n \"globals\": \"^15.14.0\",\n \"prettier\": \"^3.4.2\",\n \"react\": \"^18.2.0\",\n \"tsup\": \"^8.0.2\",\n \"typescript\": \"^5.7.3\",\n \"typescript-eslint\": \"^8.21.0\"\n },\n \"peerDependencies\": {\n \"react\": \">=16.8.0\"\n },\n \"dependencies\": {\n \"tiny-emitter\": \"^2.1.0\"\n }\n}","import { TinyEmitter } from 'tiny-emitter'\n\nexport type SusanoLoaderConfig<T> = {\n onLoaded?: (loader: SusanoLoader<T>) => void\n onProgress?: (loader: SusanoLoader<T>) => void\n}\n\nexport class SusanoLoader<T> extends TinyEmitter implements ISusanoLoader<T> {\n public url: string\n public loaded: boolean\n public content: T\n public config: SusanoLoaderConfig<T>\n public weight: number\n public progress: number\n\n constructor(url: string, _cnfg: SusanoLoaderConfig<T> = {}) {\n super()\n this.url = url\n this.loaded = false\n this.content = null as unknown as T\n this.config = _cnfg\n this.weight = 1\n this.progress = 0\n }\n\n load(): Promise<T> {\n throw new Error('Method not implemented')\n }\n\n _onLoaded() {\n this.loaded = true\n this.progress = 1\n this.emit('loaded', this)\n this.config.onLoaded?.(this)\n }\n\n _onProgress(value: number) {\n this.progress = value\n this.emit('progress', this)\n this.config.onProgress?.(this)\n }\n\n /**\n * This is ment to be used as a way to attach to master loader events\n */\n _appendConfig(cnfg: SusanoLoaderConfig<T>) {\n const _onLoaded = this.config.onLoaded\n this.config.onLoaded = (loader) => {\n _onLoaded?.(loader)\n cnfg.onLoaded?.(loader)\n }\n\n const _onProgress = this.config.onProgress\n\n this.config.onProgress = (loader) => {\n _onProgress?.(loader)\n cnfg.onProgress?.(loader)\n }\n }\n}\n\nexport interface ISusanoLoader<T> {\n load: () => Promise<T>\n}\n","import { ISusanoLoader, SusanoLoaderConfig, SusanoLoader } from './loader'\n\nexport type SusanoImageLoaderConfig = SusanoLoaderConfig<HTMLImageElement> & {\n srcSet?: string\n sizes?: string\n}\n\nexport class ImageLoader extends SusanoLoader<HTMLImageElement> implements ISusanoLoader<HTMLImageElement> {\n public static type = 'image' as const\n public srcSet?: string\n public sizes?: string\n\n constructor(url: string, cnfg: SusanoImageLoaderConfig = {}) {\n super(url, cnfg)\n this.content = new Image()\n this.srcSet = cnfg.srcSet\n this.sizes = cnfg.sizes\n }\n\n load(): Promise<HTMLImageElement> {\n return new Promise((resolve, reject) => {\n if (this.loaded) {\n this._onLoaded.call(this)\n resolve(this.content)\n return\n }\n\n if (this.srcSet) this.content.srcset = this.srcSet\n if (this.sizes) this.content.sizes = this.sizes\n this.content.src = this.url\n\n this.content.onload = () => {\n this._onLoaded.call(this)\n resolve(this.content)\n }\n\n this.content.onerror = (e) => reject(e)\n })\n }\n}\n","import { ISusanoLoader, SusanoLoaderConfig, SusanoLoader } from './loader'\n\ntype LoadEvent = 'canplay' | 'canplaythrough'\n\nexport type SusanoVideoLoaderConfig = SusanoLoaderConfig<HTMLVideoElement> & {\n video?: HTMLVideoElement\n loadEvent?: LoadEvent\n}\n\nexport class VideoLoader extends SusanoLoader<HTMLVideoElement> implements ISusanoLoader<HTMLVideoElement> {\n public static type = 'video' as const\n public loadEvent: LoadEvent\n\n constructor(url: string, cnfg: SusanoVideoLoaderConfig = {}) {\n super(url, cnfg)\n this.content = cnfg.video || document.createElement('video')\n this.loadEvent = cnfg.loadEvent || 'canplay'\n }\n\n load(): Promise<HTMLVideoElement> {\n return new Promise((resolve, reject) => {\n const video = this.content\n\n if (this.loaded) {\n this._onLoaded.call(this)\n resolve(this.content)\n return\n }\n\n video.src = this.url\n\n video.addEventListener(this.loadEvent, () => {\n this._onLoaded.call(this)\n resolve(this.content)\n })\n\n video.addEventListener('error', (e) => reject(e))\n })\n }\n}\n","import { ISusanoLoader, SusanoLoaderConfig, SusanoLoader } from './loader'\n\ntype LoadEvent = 'canplay' | 'canplaythrough'\n\nexport type SusanoAudioLoaderConfig = SusanoLoaderConfig<HTMLAudioElement> & {\n audio?: HTMLAudioElement\n loadEvent?: LoadEvent\n}\n\nexport class AudioLoader extends SusanoLoader<HTMLAudioElement> implements ISusanoLoader<HTMLAudioElement> {\n public static type = 'audio' as const\n public loadEvent: LoadEvent\n\n constructor(url: string, cnfg: SusanoAudioLoaderConfig = {}) {\n super(url, cnfg)\n this.content = cnfg.audio || document.createElement('audio')\n this.loadEvent = cnfg.loadEvent || 'canplay'\n }\n\n load(): Promise<HTMLAudioElement> {\n return new Promise((resolve, reject) => {\n const audio = this.content\n\n if (this.loaded) {\n this._onLoaded.call(this)\n resolve(this.content)\n return\n }\n\n audio.src = this.url\n\n audio.addEventListener(this.loadEvent, () => {\n this._onLoaded.call(this)\n resolve(this.content)\n })\n\n audio.addEventListener('error', (e) => reject(e))\n })\n }\n}\n","import { SusanoLoader, SusanoLoaderConfig } from './loader'\n\nexport type GenericLoadFn = (config: {\n url: string\n done: (generic: any) => void\n error: (error: Error) => void\n progress: (progress: number) => void\n}) => void\n\nexport type SusanoGenericLoaderConfig = SusanoLoaderConfig<any> & {\n loadFn: GenericLoadFn\n}\n\nexport class GenericLoader extends SusanoLoader<any> {\n public static type = 'generic' as const\n public loadFn: GenericLoadFn\n\n constructor(url: string, cnfg: SusanoGenericLoaderConfig) {\n super(url, cnfg)\n this.loadFn = cnfg.loadFn\n }\n\n load(): Promise<any> {\n return new Promise((resolve, reject) => {\n if (!this.loadFn) {\n reject(new Error('No load function provided'))\n return\n }\n\n if (this.loaded) {\n this._onLoaded.call(this)\n resolve(this.content)\n return\n }\n\n this.loadFn({\n url: this.url,\n done: (generic: any) => {\n this.content = generic\n this._onLoaded.call(this)\n resolve(generic)\n },\n error: reject,\n /* 0 to 1 */\n progress: (value: number) => {\n this._onProgress.call(this, value)\n },\n })\n })\n }\n}\n","import { TinyEmitter } from 'tiny-emitter'\nimport { SusanoLoader } from './loaders/loader'\nimport { ImageLoader, type SusanoImageLoaderConfig } from './loaders/image'\nimport { VideoLoader, type SusanoVideoLoaderConfig } from './loaders/video'\nimport { AudioLoader, type SusanoAudioLoaderConfig } from './loaders/audio'\nimport { GenericLoader, type GenericLoadFn, type SusanoGenericLoaderConfig } from './loaders/generic'\n\nexport type LoaderTypes = {\n [K: string]: {\n type: typeof K\n loader: typeof SusanoLoader<any>\n }\n}\n\nexport type LoaderMap<T extends LoaderTypes> = {\n [K in keyof T]: T[K]['loader']\n}\n\nexport type ProgressEventArgs = {\n value: number\n item: SusanoLoader<unknown>\n susano: Susano<any>\n}\n\n/**\n * Main loader class that manages loading of different asset types\n * @template T Type definition for the loaders to be used, extending LoaderTypes\n * @extends TinyEmitter\n */\nexport class Susano<T extends LoaderTypes> extends TinyEmitter {\n private loaders: LoaderMap<T> = {} as LoaderMap<T>\n public queue: InstanceType<T[keyof T]['loader']>[] = []\n public active: InstanceType<T[keyof T]['loader']>[] = []\n public items: Map<string, InstanceType<T[keyof T]['loader']>> = new Map()\n public loadCount: number = 0\n public loadLength: number = 0\n\n constructor() {\n super()\n }\n\n add<K extends keyof T>(\n url: string,\n cnfg: {\n type: K\n loaderArgs?: ConstructorParameters<T[K]['loader']>[1]\n }\n ): InstanceType<T[K]['loader']> {\n const Loader = this.loaders[cnfg.type]\n\n if (!Loader) throw new Error(`Loader for type ${String(cnfg.type)} not found`)\n\n let item = this.items.get(url)\n\n if (!item) {\n item = new Loader(url, cnfg.loaderArgs) as InstanceType<T[K]['loader']>\n this.items.set(url, item)\n } else if (cnfg.loaderArgs) {\n item._appendConfig(cnfg.loaderArgs)\n }\n\n this.queue.push(item)\n\n return item\n }\n\n load<K extends keyof T>(\n url: string,\n cnfg: {\n type: K\n loaderArgs?: ConstructorParameters<T[K]['loader']>[1]\n }\n ) {\n const Loader = this.loaders[cnfg.type]\n if (!Loader) throw new Error(`Loader for type ${String(cnfg.type)} not found`)\n\n let item = this.items.get(url)\n\n if (!item) {\n item = new Loader(url, cnfg.loaderArgs) as InstanceType<T[K]['loader']>\n this.items.set(url, item)\n } else if (cnfg.loaderArgs) {\n item._appendConfig(cnfg.loaderArgs)\n }\n\n item.load()\n\n return item\n }\n\n registerLoader<K extends keyof T>(type: K, loader: T[K]['loader']) {\n this.loaders[type] = loader\n }\n\n _onProgress(item: SusanoLoader<unknown>) {\n this.loadCount++\n\n // const idx = this.active.indexOf(item);\n // this.active.splice(idx, 1);\n\n const progress = this.loadCount / this.loadLength\n\n this.emit('progress', {\n value: progress,\n item: item,\n susano: this,\n } satisfies ProgressEventArgs)\n\n if (progress === 1) {\n this.emit('completed', this)\n return\n }\n }\n\n start({\n onCompleted,\n onProgress,\n }: {\n onCompleted?: (susano: Susano<T>) => void\n onProgress?: (progress: { value: number; item: SusanoLoader<unknown>; susano: Susano<T> }) => void\n } = {}) {\n this.active = this.queue.splice(0, this.queue.length)\n this.loadLength = this.active.length\n this.loadCount = 0\n\n this.emit('start', this)\n\n if (onProgress) this.on('progress', onProgress)\n\n this.once('completed', () => {\n onCompleted?.(this)\n if (onProgress) this.off('progress', onProgress)\n })\n\n this.active.map((item) => {\n item.once('loaded', () => {\n this._onProgress(item)\n })\n\n item.load()\n })\n }\n}\n\nexport const susano = new Susano<{\n image: {\n type: 'image'\n loader: typeof ImageLoader\n }\n video: {\n type: 'video'\n loader: typeof VideoLoader\n }\n audio: {\n type: 'audio'\n loader: typeof AudioLoader\n }\n generic: {\n type: 'generic'\n loader: typeof GenericLoader\n }\n}>()\n\nsusano.registerLoader(ImageLoader.type, ImageLoader)\nsusano.registerLoader(VideoLoader.type, VideoLoader)\nsusano.registerLoader(AudioLoader.type, AudioLoader)\nsusano.registerLoader(GenericLoader.type, GenericLoader)\n\nexport type {\n GenericLoadFn,\n SusanoImageLoaderConfig,\n SusanoVideoLoaderConfig,\n SusanoAudioLoaderConfig,\n SusanoGenericLoaderConfig,\n GenericLoader,\n ImageLoader,\n VideoLoader,\n AudioLoader,\n}\n","import { version } from '../../package.json'\n\nexport const VERSION = version\nexport * from './core'\n"]}
1
+ {"version":3,"sources":["../package.json","../packages/core/loaders/loader.ts","../packages/core/loaders/image.ts","../packages/core/loaders/video.ts","../packages/core/loaders/audio.ts","../packages/core/loaders/generic.ts","../packages/core/core.tsx","../packages/core/index.ts"],"names":["TinyEmitter"],"mappings":"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","file":"index.mjs","sourcesContent":["{\n \"name\": \"@joycostudio/susano\",\n \"publishConfig\": {\n \"registry\": \"https://registry.npmjs.org\",\n \"access\": \"public\"\n },\n \"version\": \"0.1.2\",\n \"description\": \"Asset load orchestration made easy\",\n \"main\": \"dist/index.js\",\n \"module\": \"dist/index.mjs\",\n \"types\": \"dist/index.d.ts\",\n \"files\": [\n \"dist\"\n ],\n \"scripts\": {\n \"build\": \"tsup\",\n \"dev\": \"concurrently \\\"tsup --watch\\\" \\\"cd templates/basic && pnpm dev\\\"\",\n \"typecheck\": \"tsc --noEmit\",\n \"version:package\": \"pnpm changeset version\",\n \"release\": \"pnpm build && pnpm changeset publish\",\n \"lint\": \"eslint -c ./eslint.config.mjs . --fix --no-cache\"\n },\n \"packageManager\": \"pnpm@10.29.2\",\n \"author\": \"@joycostudio\",\n \"license\": \"ISC\",\n \"devDependencies\": {\n \"@changesets/cli\": \"^2.27.11\",\n \"@eslint/js\": \"^9.18.0\",\n \"@types/node\": \"^20.11.24\",\n \"@types/react\": \"^18.2.61\",\n \"@typescript-eslint/eslint-plugin\": \"^8.21.0\",\n \"@typescript-eslint/parser\": \"^8.21.0\",\n \"concurrently\": \"^9.1.2\",\n \"eslint\": \"^9.18.0\",\n \"eslint-config-prettier\": \"^10.0.1\",\n \"eslint-plugin-prettier\": \"^5.2.3\",\n \"eslint-plugin-react\": \"^7.37.4\",\n \"eslint-plugin-react-compiler\": \"19.0.0-beta-decd7b8-20250118\",\n \"globals\": \"^15.14.0\",\n \"prettier\": \"^3.4.2\",\n \"react\": \"^18.2.0\",\n \"tsup\": \"^8.0.2\",\n \"typescript\": \"^5.7.3\",\n \"typescript-eslint\": \"^8.21.0\"\n },\n \"peerDependencies\": {\n \"react\": \">=16.8.0\"\n },\n \"dependencies\": {\n \"tiny-emitter\": \"^2.1.0\"\n }\n}","import { TinyEmitter } from 'tiny-emitter'\n\nexport type SusanoLoaderConfig<T> = {\n onLoaded?: (loader: SusanoLoader<T>) => void\n onProgress?: (loader: SusanoLoader<T>) => void\n}\n\nexport class SusanoLoader<T> extends TinyEmitter implements ISusanoLoader<T> {\n public url: string\n public loaded: boolean\n public content: T\n public config: SusanoLoaderConfig<T>\n public weight: number\n public progress: number\n public promise!: Promise<T>\n private _resolve!: (value: T) => void\n private _reject!: (error: unknown) => void\n\n constructor(url: string, _cnfg: SusanoLoaderConfig<T> = {}) {\n super()\n this.url = url\n this.loaded = false\n this.content = null as unknown as T\n this.config = _cnfg\n this.weight = 1\n this.progress = 0\n\n this._resetPromise()\n }\n\n load(): Promise<T> {\n throw new Error('Method not implemented')\n }\n\n _onLoaded() {\n this.loaded = true\n this.progress = 1\n this._resolve(this.content)\n this.emit('loaded', this)\n this.config.onLoaded?.(this)\n }\n\n _onError(error: unknown) {\n this._reject(error)\n this.progress = 0\n this._resetPromise()\n this.emit('error', error)\n }\n\n private _resetPromise() {\n this.promise = new Promise<T>((resolve, reject) => {\n this._resolve = resolve\n this._reject = reject\n })\n }\n\n _onProgress(value: number) {\n this.progress = value\n this.emit('progress', this)\n this.config.onProgress?.(this)\n }\n\n /**\n * This is ment to be used as a way to attach to master loader events\n */\n _appendConfig(cnfg: SusanoLoaderConfig<T>) {\n const _onLoaded = this.config.onLoaded\n this.config.onLoaded = (loader) => {\n _onLoaded?.(loader)\n cnfg.onLoaded?.(loader)\n }\n\n const _onProgress = this.config.onProgress\n\n this.config.onProgress = (loader) => {\n _onProgress?.(loader)\n cnfg.onProgress?.(loader)\n }\n }\n}\n\nexport interface ISusanoLoader<T> {\n load: () => Promise<T>\n}\n","import { ISusanoLoader, SusanoLoaderConfig, SusanoLoader } from './loader'\n\nexport type SusanoImageLoaderConfig = SusanoLoaderConfig<HTMLImageElement> & {\n srcSet?: string\n sizes?: string\n}\n\nexport class ImageLoader extends SusanoLoader<HTMLImageElement> implements ISusanoLoader<HTMLImageElement> {\n public static type = 'image' as const\n public srcSet?: string\n public sizes?: string\n\n constructor(url: string, cnfg: SusanoImageLoaderConfig = {}) {\n super(url, cnfg)\n this.content = new Image()\n this.srcSet = cnfg.srcSet\n this.sizes = cnfg.sizes\n }\n\n load(): Promise<HTMLImageElement> {\n if (this.loaded) { this._onLoaded(); return this.promise }\n\n if (this.srcSet) this.content.srcset = this.srcSet\n if (this.sizes) this.content.sizes = this.sizes\n this.content.src = this.url\n\n this.content.onload = () => this._onLoaded()\n this.content.onerror = (e) => this._onError(e)\n\n return this.promise\n }\n}\n","import { ISusanoLoader, SusanoLoaderConfig, SusanoLoader } from './loader'\n\ntype LoadEvent = 'canplay' | 'canplaythrough'\n\nexport type SusanoVideoLoaderConfig = SusanoLoaderConfig<HTMLVideoElement> & {\n video?: HTMLVideoElement\n loadEvent?: LoadEvent\n}\n\nexport class VideoLoader extends SusanoLoader<HTMLVideoElement> implements ISusanoLoader<HTMLVideoElement> {\n public static type = 'video' as const\n public loadEvent: LoadEvent\n\n constructor(url: string, cnfg: SusanoVideoLoaderConfig = {}) {\n super(url, cnfg)\n this.content = cnfg.video || document.createElement('video')\n this.loadEvent = cnfg.loadEvent || 'canplay'\n }\n\n load(): Promise<HTMLVideoElement> {\n if (this.loaded) { this._onLoaded(); return this.promise }\n\n const el = this.content\n el.src = this.url\n el.addEventListener(this.loadEvent, () => this._onLoaded(), { once: true })\n el.addEventListener('error', (e) => this._onError(e), { once: true })\n\n return this.promise\n }\n}\n","import { ISusanoLoader, SusanoLoaderConfig, SusanoLoader } from './loader'\n\ntype LoadEvent = 'canplay' | 'canplaythrough'\n\nexport type SusanoAudioLoaderConfig = SusanoLoaderConfig<HTMLAudioElement> & {\n audio?: HTMLAudioElement\n loadEvent?: LoadEvent\n}\n\nexport class AudioLoader extends SusanoLoader<HTMLAudioElement> implements ISusanoLoader<HTMLAudioElement> {\n public static type = 'audio' as const\n public loadEvent: LoadEvent\n\n constructor(url: string, cnfg: SusanoAudioLoaderConfig = {}) {\n super(url, cnfg)\n this.content = cnfg.audio || document.createElement('audio')\n this.loadEvent = cnfg.loadEvent || 'canplay'\n }\n\n load(): Promise<HTMLAudioElement> {\n if (this.loaded) { this._onLoaded(); return this.promise }\n\n const el = this.content\n el.src = this.url\n el.addEventListener(this.loadEvent, () => this._onLoaded(), { once: true })\n el.addEventListener('error', (e) => this._onError(e), { once: true })\n\n return this.promise\n }\n}\n","import { SusanoLoader, SusanoLoaderConfig } from './loader'\n\nexport type GenericLoadFn = (config: {\n url: string\n done: (generic: any) => void\n error: (error: Error) => void\n progress: (progress: number) => void\n}) => void\n\nexport type SusanoGenericLoaderConfig = SusanoLoaderConfig<any> & {\n loadFn: GenericLoadFn\n}\n\nexport class GenericLoader extends SusanoLoader<any> {\n public static type = 'generic' as const\n public loadFn: GenericLoadFn\n\n constructor(url: string, cnfg: SusanoGenericLoaderConfig) {\n super(url, cnfg)\n this.loadFn = cnfg.loadFn\n }\n\n load(): Promise<any> {\n if (!this.loadFn) { this._onError(new Error('No load function provided')); return this.promise }\n if (this.loaded) { this._onLoaded(); return this.promise }\n\n this.loadFn({\n url: this.url,\n done: (generic: any) => { this.content = generic; this._onLoaded() },\n error: (err) => this._onError(err),\n /* 0 to 1 */\n progress: (value: number) => this._onProgress(value),\n })\n\n return this.promise\n }\n}\n","import { TinyEmitter } from 'tiny-emitter'\nimport { SusanoLoader } from './loaders/loader'\nimport { ImageLoader } from './loaders/image'\nimport { VideoLoader } from './loaders/video'\nimport { AudioLoader } from './loaders/audio'\nimport { GenericLoader } from './loaders/generic'\n\nexport type LoaderTypes = {\n [K: string]: {\n type: typeof K\n loader: typeof SusanoLoader<any>\n }\n}\n\nexport type LoaderMap<T extends LoaderTypes> = {\n [K in keyof T]: T[K]['loader']\n}\n\nexport type ProgressEventArgs = {\n value: number\n item: SusanoLoader<unknown>\n susano: Susano<any>\n}\n\n/**\n * Main loader class that manages loading of different asset types\n * @template T Type definition for the loaders to be used, extending LoaderTypes\n * @extends TinyEmitter\n */\nexport class Susano<T extends LoaderTypes> extends TinyEmitter {\n private loaders: LoaderMap<T> = {} as LoaderMap<T>\n public queue: InstanceType<T[keyof T]['loader']>[] = []\n public active: InstanceType<T[keyof T]['loader']>[] = []\n public items: Map<string, InstanceType<T[keyof T]['loader']>> = new Map()\n public loadCount: number = 0\n public loadLength: number = 0\n\n constructor() {\n super()\n }\n\n add<K extends keyof T>(\n url: string,\n cnfg: {\n type: K\n loaderArgs?: ConstructorParameters<T[K]['loader']>[1]\n }\n ): InstanceType<T[K]['loader']> {\n const Loader = this.loaders[cnfg.type]\n\n if (!Loader) throw new Error(`Loader for type ${String(cnfg.type)} not found`)\n\n let item = this.items.get(url)\n\n if (!item) {\n item = new Loader(url, cnfg.loaderArgs) as InstanceType<T[K]['loader']>\n this.items.set(url, item)\n } else if (cnfg.loaderArgs) {\n item._appendConfig(cnfg.loaderArgs)\n }\n\n this.queue.push(item)\n\n return item\n }\n\n load<K extends keyof T>(\n url: string,\n cnfg: {\n type: K\n loaderArgs?: ConstructorParameters<T[K]['loader']>[1]\n }\n ) {\n const Loader = this.loaders[cnfg.type]\n if (!Loader) throw new Error(`Loader for type ${String(cnfg.type)} not found`)\n\n let item = this.items.get(url)\n\n if (!item) {\n item = new Loader(url, cnfg.loaderArgs) as InstanceType<T[K]['loader']>\n this.items.set(url, item)\n } else if (cnfg.loaderArgs) {\n item._appendConfig(cnfg.loaderArgs)\n }\n\n item.load()\n\n return item\n }\n\n registerLoader<K extends keyof T>(type: K, loader: T[K]['loader']) {\n this.loaders[type] = loader\n }\n\n _onProgress(item: SusanoLoader<unknown>) {\n this.loadCount++\n\n // const idx = this.active.indexOf(item);\n // this.active.splice(idx, 1);\n\n const progress = this.loadCount / this.loadLength\n\n this.emit('progress', {\n value: progress,\n item: item,\n susano: this,\n } satisfies ProgressEventArgs)\n\n if (progress === 1) {\n this.emit('completed', this)\n return\n }\n }\n\n start({\n onCompleted,\n onProgress,\n }: {\n onCompleted?: (susano: Susano<T>) => void\n onProgress?: (progress: { value: number; item: SusanoLoader<unknown>; susano: Susano<T> }) => void\n } = {}) {\n this.active = this.queue.splice(0, this.queue.length)\n this.loadLength = this.active.length\n this.loadCount = 0\n\n this.emit('start', this)\n\n if (onProgress) this.on('progress', onProgress)\n\n this.once('completed', () => {\n onCompleted?.(this)\n if (onProgress) this.off('progress', onProgress)\n })\n\n this.active.map((item) => {\n item.once('loaded', () => {\n this._onProgress(item)\n })\n\n item.load()\n })\n }\n}\n\nexport const susano = new Susano<{\n image: {\n type: 'image'\n loader: typeof ImageLoader\n }\n video: {\n type: 'video'\n loader: typeof VideoLoader\n }\n audio: {\n type: 'audio'\n loader: typeof AudioLoader\n }\n generic: {\n type: 'generic'\n loader: typeof GenericLoader\n }\n}>()\n\nsusano.registerLoader(ImageLoader.type, ImageLoader)\nsusano.registerLoader(VideoLoader.type, VideoLoader)\nsusano.registerLoader(AudioLoader.type, AudioLoader)\nsusano.registerLoader(GenericLoader.type, GenericLoader)\n\nexport * from './loaders/loader'\nexport * from './loaders/image'\nexport * from './loaders/video'\nexport * from './loaders/audio'\nexport * from './loaders/generic'\n","import { version } from '../../package.json'\n\nexport const VERSION = version\nexport * from './core'\n"]}
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "registry": "https://registry.npmjs.org",
5
5
  "access": "public"
6
6
  },
7
- "version": "0.1.0",
7
+ "version": "0.1.2",
8
8
  "description": "Asset load orchestration made easy",
9
9
  "main": "dist/index.js",
10
10
  "module": "dist/index.mjs",