@streamscloud/embeddable 14.0.1 → 15.0.0-rc.0

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.
Files changed (54) hide show
  1. package/dist/core/analytics.installation-id.d.ts +5 -0
  2. package/dist/core/{analytics.profile-id.js → analytics.installation-id.js} +20 -10
  3. package/dist/external-api/data-providers/internal-media-center-analytics-handler.d.ts +14 -14
  4. package/dist/external-api/data-providers/internal-media-center-analytics-handler.js +170 -19
  5. package/dist/external-api/data-providers/internal-post-analytics-handler.d.ts +7 -7
  6. package/dist/external-api/data-providers/internal-post-analytics-handler.js +72 -11
  7. package/dist/external-api/data-providers/internal-stream-analytics-handler.d.ts +12 -13
  8. package/dist/external-api/data-providers/internal-stream-analytics-handler.js +162 -18
  9. package/dist/external-api/data-providers/mapper.d.ts +3 -0
  10. package/dist/external-api/data-providers/mapper.js +18 -0
  11. package/dist/external-api/data-providers/post-data-loaders/mapper.js +1 -3
  12. package/dist/media-center/media-center/discover/discover-view.svelte +33 -11
  13. package/dist/media-center/media-center/menu/menu.svelte +5 -3
  14. package/dist/media-center/media-center/streams-in-category/streams-in-category-panel.svelte +6 -2
  15. package/dist/posts/post-viewer/cmp.post-viewer.svelte.d.ts +1 -1
  16. package/dist/posts/posts-player/posts-player-view.svelte +9 -12
  17. package/dist/posts/posts-player/types.d.ts +3 -5
  18. package/dist/streams/streams-player/streams-player-view.svelte +15 -16
  19. package/dist/streams/streams-player/types.d.ts +0 -1
  20. package/dist/ui/button/resources/button-theme.svelte +4 -2
  21. package/dist/ui/icon/cmp.icon.svelte +1 -1
  22. package/dist/ui/player/button/cmp.player-button.svelte +3 -1
  23. package/dist/ui/player/button/cmp.player-buttons-group.svelte +3 -1
  24. package/dist/ui/player/index.d.ts +1 -0
  25. package/dist/ui/player/index.js +1 -0
  26. package/dist/ui/player/{content-player/cmp.content-player.svelte → player/cmp.player.svelte} +16 -16
  27. package/dist/ui/player/{content-player/cmp.content-player.svelte.d.ts → player/cmp.player.svelte.d.ts} +17 -8
  28. package/dist/ui/player/{content-player → player}/controls-and-attachments.svelte +1 -1
  29. package/dist/ui/player/{content-player → player}/controls-and-attachments.svelte.d.ts +17 -8
  30. package/dist/ui/player/player/index.d.ts +3 -0
  31. package/dist/ui/player/player/index.js +3 -0
  32. package/dist/ui/player/{content-player → player}/overview-panel.svelte +3 -1
  33. package/dist/ui/player/{content-player → player}/overview-panel.svelte.d.ts +18 -9
  34. package/dist/ui/player/player/player-config.svelte.d.ts +21 -0
  35. package/dist/ui/player/player/player-config.svelte.js +19 -0
  36. package/dist/ui/player/{content-player/content-player-settings.svelte.d.ts → player/player-settings.svelte.d.ts} +1 -1
  37. package/dist/ui/player/{content-player/content-player-settings.svelte.js → player/player-settings.svelte.js} +1 -1
  38. package/dist/ui/player/{content-player → player}/ui-manager.svelte.d.ts +1 -1
  39. package/dist/ui/player/{content-player → player}/ui-manager.svelte.js +1 -1
  40. package/dist/ui/player/providers/chunks-player-buffer/player-chunk.svelte.d.ts +3 -5
  41. package/dist/ui/player/providers/chunks-player-buffer/player-chunk.svelte.js +39 -39
  42. package/dist/ui/player/providers/chunks-player-buffer/player-chunks-manager.svelte.d.ts +4 -4
  43. package/dist/ui/player/providers/chunks-player-buffer/player-chunks-manager.svelte.js +80 -63
  44. package/dist/ui/player/providers/default-chunks-player-buffer.svelte.js +5 -1
  45. package/dist/ui/player/slider/cmp.player-slider.svelte.d.ts +14 -5
  46. package/dist/ui/player/slider-horizontal/cmp.slider.svelte +6 -2
  47. package/dist/ui/player/slider-horizontal/cmp.slider.svelte.d.ts +12 -5
  48. package/dist/ui/shadow-dom/cmp.shadow-root.svelte +2 -2
  49. package/package.json +2 -2
  50. package/dist/core/analytics.profile-id.d.ts +0 -5
  51. package/dist/ui/player/content-player/content-player-config.svelte.d.ts +0 -29
  52. package/dist/ui/player/content-player/content-player-config.svelte.js +0 -27
  53. package/dist/ui/player/content-player/index.d.ts +0 -3
  54. package/dist/ui/player/content-player/index.js +0 -3
@@ -59,7 +59,6 @@ const styles = $derived.by(() => {
59
59
  z-index: 0;
60
60
  border-radius: 0.5rem 0 0 0.5rem;
61
61
  background: var(--_overview-panel--background);
62
- /* Set 'container-type: inline-size;' to reference container*/
63
62
  }
64
63
  .overview-panel__content {
65
64
  width: 100%;
@@ -71,6 +70,9 @@ const styles = $derived.by(() => {
71
70
  overflow: hidden;
72
71
  container-type: inline-size;
73
72
  }
73
+ .overview-panel {
74
+ /* Set 'container-type: inline-size;' to reference container*/
75
+ }
74
76
  @container (width < 576px) {
75
77
  .overview-panel {
76
78
  width: 100%;
@@ -1,12 +1,12 @@
1
- import type { ContentPlayerConfig } from './content-player-config.svelte';
2
- import type { ContentPlayerUIManager } from './ui-manager.svelte';
1
+ import type { PlayerConfig } from './player-config.svelte.js';
2
+ import type { PlayerUIManager } from './ui-manager.svelte';
3
3
  import type { Snippet } from 'svelte';
4
- declare class __sveltets_Render<T extends {
4
+ declare function $$render<T extends {
5
5
  id: string;
6
- }> {
7
- props(): {
8
- config: ContentPlayerConfig<T>;
9
- uiManager: ContentPlayerUIManager;
6
+ }>(): {
7
+ props: {
8
+ config: PlayerConfig<T>;
9
+ uiManager: PlayerUIManager;
10
10
  position: {
11
11
  top: number;
12
12
  bottom: number;
@@ -14,8 +14,17 @@ declare class __sveltets_Render<T extends {
14
14
  };
15
15
  children: Snippet;
16
16
  };
17
- events(): {};
18
- slots(): {};
17
+ exports: {};
18
+ bindings: "";
19
+ slots: {};
20
+ events: {};
21
+ };
22
+ declare class __sveltets_Render<T extends {
23
+ id: string;
24
+ }> {
25
+ props(): ReturnType<typeof $$render<T>>['props'];
26
+ events(): ReturnType<typeof $$render<T>>['events'];
27
+ slots(): ReturnType<typeof $$render<T>>['slots'];
19
28
  bindings(): "";
20
29
  exports(): {};
21
30
  }
@@ -0,0 +1,21 @@
1
+ import type { ICloseOrchestrator } from '../close-orchestrator';
2
+ import type { IPlayerBuffer } from '../providers';
3
+ import type { PlayerSliderCallbacks } from '../slider/types';
4
+ import { PlayerSettings } from './player-settings.svelte';
5
+ import { PlayerUIManager } from './ui-manager.svelte';
6
+ export declare class PlayerConfig<T extends {
7
+ id: string;
8
+ }> {
9
+ playerBuffer: IPlayerBuffer<T> | null;
10
+ readonly settings: PlayerSettings;
11
+ readonly playerSliderCallbacks: PlayerSliderCallbacks | undefined;
12
+ readonly closeOrchestrator: ICloseOrchestrator;
13
+ readonly uiManager: PlayerUIManager;
14
+ constructor(init: {
15
+ playerBuffer: IPlayerBuffer<T> | null;
16
+ settings?: PlayerSettings;
17
+ playerSliderCallbacks?: PlayerSliderCallbacks;
18
+ closeOrchestrator: ICloseOrchestrator;
19
+ });
20
+ get playerColors(): import("../colors").PlayerColors;
21
+ }
@@ -0,0 +1,19 @@
1
+ import { PlayerSettings } from './player-settings.svelte';
2
+ import { PlayerUIManager } from './ui-manager.svelte';
3
+ export class PlayerConfig {
4
+ playerBuffer = $state.raw(null);
5
+ settings;
6
+ playerSliderCallbacks;
7
+ closeOrchestrator;
8
+ uiManager = new PlayerUIManager();
9
+ constructor(init) {
10
+ const { playerBuffer, settings, playerSliderCallbacks, closeOrchestrator } = init;
11
+ this.playerBuffer = playerBuffer;
12
+ this.settings = settings || new PlayerSettings();
13
+ this.playerSliderCallbacks = playerSliderCallbacks;
14
+ this.closeOrchestrator = closeOrchestrator;
15
+ }
16
+ get playerColors() {
17
+ return this.settings.playerColors;
18
+ }
19
+ }
@@ -1,7 +1,7 @@
1
1
  import type { Locale } from '../../../core/locale';
2
2
  import { type ThemeValue } from '../../../core/theme';
3
3
  import { PlayerColors } from '../colors';
4
- export declare class ContentPlayerSettings {
4
+ export declare class PlayerSettings {
5
5
  locale: Locale;
6
6
  showStreamsCloudWatermark: boolean;
7
7
  allPlayerColors: Record<ThemeValue, PlayerColors>;
@@ -1,6 +1,6 @@
1
1
  import { Theme } from '../../../core/theme';
2
2
  import { PlayerColors } from '../colors';
3
- export class ContentPlayerSettings {
3
+ export class PlayerSettings {
4
4
  locale = $state('en');
5
5
  showStreamsCloudWatermark = $state(false);
6
6
  allPlayerColors = $state.raw({
@@ -1,4 +1,4 @@
1
- export declare class ContentPlayerUIManager {
1
+ export declare class PlayerUIManager {
2
2
  overviewCollapsed: boolean;
3
3
  readonly overviewCanBeShown: boolean;
4
4
  readonly overviewMaxWidth = 150;
@@ -1,7 +1,7 @@
1
1
  const ATTACHMENTS_MAX_WIDTH = 176;
2
2
  const OVERLAY_MAX_WIDTH = 150;
3
3
  const SAFE_AREA_SIZE = 70;
4
- export class ContentPlayerUIManager {
4
+ export class PlayerUIManager {
5
5
  overviewCollapsed = $state(true);
6
6
  overviewCanBeShown = $derived.by(() => this.overviewMaxWidth <= this.sidePanelsMaxWidth);
7
7
  overviewMaxWidth = OVERLAY_MAX_WIDTH;
@@ -5,11 +5,9 @@ export declare class PlayerChunk<TItem extends WithId, TChunk extends WithId> {
5
5
  readonly items: TItem[];
6
6
  readonly chunkItems: PlayerChunkItem<TItem>[];
7
7
  readonly activeChunkItem: PlayerChunkItem<TItem>;
8
- readonly isEmpty: boolean;
9
- isFullyLoaded: boolean;
10
8
  private _chunkItems;
11
9
  private _activeItemIndex;
12
- private _isLoading;
10
+ private _fetchDeferred;
13
11
  private _itemsLoader;
14
12
  constructor(data: {
15
13
  chunk: TChunk;
@@ -24,9 +22,9 @@ export declare class PlayerChunk<TItem extends WithId, TChunk extends WithId> {
24
22
  };
25
23
  });
26
24
  get isLoading(): boolean;
25
+ get canLoadMore(): boolean;
27
26
  get activeItemIndex(): number;
28
27
  loadMore: () => Promise<TItem[]>;
29
- setActiveItemIndex: (index: number, warmUp?: boolean) => Promise<void>;
28
+ setActiveItemIndex: (index: number) => Promise<void>;
30
29
  mutateChunkItems: (items: PlayerChunkItem<TItem>[]) => void;
31
- warmUp: () => Promise<void>;
32
30
  }
@@ -1,73 +1,73 @@
1
1
  import { ContinuationToken } from '../../../../core/continuation-token';
2
2
  import { CursorDataLoader } from '../../../../core/data-loaders';
3
+ import { Deferred } from '../../../../core/deferred';
3
4
  import { PlayerChunkItem } from './player-chunk-item.svelte';
4
- const CHUNK_ITEMS_BUFFER_SIZE = 5;
5
5
  export class PlayerChunk {
6
6
  model;
7
7
  items = $derived.by(() => this._chunkItems.map((i) => i.model));
8
8
  chunkItems = $derived.by(() => this._chunkItems);
9
9
  activeChunkItem = $derived.by(() => this._chunkItems[this._activeItemIndex] ?? null);
10
- isEmpty = $derived.by(() => this.isFullyLoaded && this._chunkItems.length === 0);
11
- isFullyLoaded = $state(false);
12
10
  _chunkItems = $state.raw([]);
13
11
  _activeItemIndex = $state(0);
14
- _isLoading = $state(false);
12
+ _fetchDeferred = $state.raw(null);
15
13
  _itemsLoader;
16
14
  constructor(data) {
17
15
  const { chunk, provider, callbacks } = data;
18
16
  this.model = chunk;
19
17
  this._itemsLoader = new CursorDataLoader({
20
18
  loadPage: async (continuationToken) => {
21
- if (this.isFullyLoaded) {
19
+ if (this._fetchDeferred) {
20
+ return await this._fetchDeferred.promise;
21
+ }
22
+ if (!this.canLoadMore) {
23
+ return null;
24
+ }
25
+ try {
26
+ this._fetchDeferred = new Deferred();
27
+ const itemsResult = await provider.loadChunkItems(this.model.id, continuationToken.toNextChunkString());
28
+ const newItems = itemsResult.items;
29
+ this._chunkItems = [
30
+ ...this._chunkItems,
31
+ ...newItems.map((item) => new PlayerChunkItem({
32
+ model: item,
33
+ chunkId: this.model.id
34
+ }))
35
+ ];
36
+ const continuationTokenResult = ContinuationToken.fromPayload(itemsResult.continuationToken);
37
+ if (!continuationTokenResult.canLoadMore) {
38
+ callbacks?.onChunkFullyLoaded(this);
39
+ }
40
+ const result = {
41
+ items: newItems,
42
+ continuationToken: continuationTokenResult
43
+ };
44
+ this._fetchDeferred.resolve(result);
45
+ return result;
46
+ }
47
+ catch {
48
+ this._fetchDeferred?.resolve(null);
22
49
  return null;
23
50
  }
24
- const result = await provider.loadChunkItems(this.model.id, continuationToken.toNextChunkString());
25
- const newItems = result.items;
26
- this._chunkItems = [
27
- ...this._chunkItems,
28
- ...newItems.map((item) => new PlayerChunkItem({
29
- model: item,
30
- chunkId: this.model.id
31
- }))
32
- ];
33
- const continuationTokenResult = ContinuationToken.fromPayload(result.continuationToken);
34
- if (!continuationTokenResult.canLoadMore) {
35
- this.isFullyLoaded = true;
36
- callbacks?.onChunkFullyLoaded(this);
51
+ finally {
52
+ this._fetchDeferred = null;
37
53
  }
38
- return {
39
- items: newItems,
40
- continuationToken: continuationTokenResult
41
- };
42
54
  }
43
55
  });
44
56
  }
45
57
  get isLoading() {
46
- return this._isLoading;
58
+ return !!this._fetchDeferred;
59
+ }
60
+ get canLoadMore() {
61
+ return this._itemsLoader.continuationToken.canLoadMore;
47
62
  }
48
63
  get activeItemIndex() {
49
64
  return this._activeItemIndex;
50
65
  }
51
66
  loadMore = () => this._itemsLoader.loadMore();
52
- setActiveItemIndex = async (index, warmUp = true) => {
67
+ setActiveItemIndex = async (index) => {
53
68
  this._activeItemIndex = index;
54
- if (warmUp) {
55
- await this.warmUp();
56
- }
57
69
  };
58
70
  mutateChunkItems = (items) => {
59
71
  this._chunkItems = items;
60
72
  };
61
- warmUp = async () => {
62
- if (this._chunkItems.length >= this._activeItemIndex + CHUNK_ITEMS_BUFFER_SIZE || this._isLoading) {
63
- return;
64
- }
65
- this._isLoading = true;
66
- try {
67
- await this.loadMore();
68
- }
69
- finally {
70
- this._isLoading = false;
71
- }
72
- };
73
73
  }
@@ -4,7 +4,7 @@ export declare class PlayerChunksManager<TItem extends WithId, TChunk extends Wi
4
4
  private provider;
5
5
  private _activeChunkIndex;
6
6
  private _loadedChunks;
7
- private _fetchDeferred;
7
+ private _warmUpDeferred;
8
8
  constructor(provider: IChunksPlayerDataProvider<TItem, TChunk>);
9
9
  get activeChunk(): PlayerChunk<TItem, TChunk>;
10
10
  get loadedChunks(): PlayerChunk<TItem, TChunk>[];
@@ -15,9 +15,9 @@ export declare class PlayerChunksManager<TItem extends WithId, TChunk extends Wi
15
15
  removeItemById: (id: string) => boolean;
16
16
  removeChunkById: (id: string) => boolean | undefined;
17
17
  initialize: () => Promise<void>;
18
- setActiveChunkIndex: (index: number) => Promise<void>;
18
+ setActiveChunkIndex: (index: number, chunkItemIndex: number) => Promise<void>;
19
19
  activateItemAtFlattenedIndex: (index: number) => Promise<void>;
20
20
  warmUp: () => Promise<void>;
21
- reset: () => void;
22
- private populateChunkAtIndex;
21
+ reset: () => Promise<void>;
22
+ private warmUpSequentially;
23
23
  }
@@ -1,12 +1,14 @@
1
1
  import { Deferred } from '../../../../core/deferred';
2
2
  import { PlayerChunk } from './player-chunk.svelte';
3
- const CHUNKS_BUFFER_SIZE = 5;
4
- const FIXED_START_INDEX = 0;
3
+ const ITEMS_BUFFER_SIZE = 10;
4
+ // Configuration: if true, always start from first item when switching chunks
5
+ // if false, activate the exact item at its position in the new chunk
6
+ const START_FROM_FIRST_ITEM_ON_CHUNK_SWITCH = true;
5
7
  export class PlayerChunksManager {
6
8
  provider;
7
9
  _activeChunkIndex = $state(-1);
8
10
  _loadedChunks = $state.raw([]);
9
- _fetchDeferred = $state.raw(null);
11
+ _warmUpDeferred = $state.raw(null);
10
12
  constructor(provider) {
11
13
  this.provider = provider;
12
14
  }
@@ -17,7 +19,7 @@ export class PlayerChunksManager {
17
19
  return this._loadedChunks;
18
20
  }
19
21
  get isLoading() {
20
- return this._fetchDeferred !== null || this._loadedChunks.some((c) => c.isLoading);
22
+ return this._warmUpDeferred !== null || this._loadedChunks.some((c) => c.isLoading);
21
23
  }
22
24
  get flattenedChunkItems() {
23
25
  return this._loadedChunks.reduce((acc, chunk) => {
@@ -42,8 +44,7 @@ export class PlayerChunksManager {
42
44
  return false;
43
45
  }
44
46
  const itemIndex = chunkWithItem.items.findIndex((item) => item.id === id);
45
- this.setActiveChunkIndex(chunkWithItemIndex);
46
- this.activeChunk.setActiveItemIndex(itemIndex);
47
+ this.setActiveChunkIndex(chunkWithItemIndex, itemIndex);
47
48
  return true;
48
49
  };
49
50
  removeItemById = (id) => {
@@ -106,37 +107,27 @@ export class PlayerChunksManager {
106
107
  else if (this._activeChunkIndex > chunkIndex) {
107
108
  newActiveChunkIndex--;
108
109
  }
109
- this.setActiveChunkIndex(newActiveChunkIndex);
110
+ this.setActiveChunkIndex(newActiveChunkIndex, 0);
110
111
  return true;
111
112
  };
112
113
  initialize = async () => {
113
- const handleInitialized = async () => {
114
- const startIndex = Math.min(FIXED_START_INDEX, this._loadedChunks.length - 1);
115
- const populateChunkResult = await this.populateChunkAtIndex(startIndex, (currentIndex) => currentIndex + 1);
116
- if (!populateChunkResult) {
117
- return;
118
- }
119
- this.setActiveChunkIndex(populateChunkResult.closestReadyChunkIndex);
120
- if (populateChunkResult.closestReadyChunkIndex === FIXED_START_INDEX &&
121
- this.provider.initialData.startItemIndex &&
122
- this.provider.initialData.startItemIndex > 0) {
123
- this.activeChunk.setActiveItemIndex(this.provider.initialData.startItemIndex);
124
- }
125
- };
126
114
  this._loadedChunks = this.provider.initialData.prefetchedChunks.map((chunk) => new PlayerChunk({ chunk, provider: { loadChunkItems: this.provider.loadChunkItems } }));
127
- const considerInitialized = this._loadedChunks.length !== 0;
128
- if (considerInitialized) {
129
- handleInitialized();
130
- }
131
115
  await this.warmUp();
132
- if (!considerInitialized) {
133
- handleInitialized();
116
+ if (this._loadedChunks.length === 0 || this.flattenedChunkItems.length === 0) {
117
+ this.provider.onEndReached?.();
118
+ return;
134
119
  }
120
+ const firstFilledChunkIndex = this._loadedChunks.findIndex((c) => c.items.length > 0);
121
+ const initialStartItemIndex = firstFilledChunkIndex === 0 && this.provider.initialData.startItemIndex && this.provider.initialData.startItemIndex > 0
122
+ ? this.provider.initialData.startItemIndex
123
+ : 0;
124
+ this.setActiveChunkIndex(firstFilledChunkIndex, initialStartItemIndex);
125
+ // Start background warm-up after initialization
126
+ this.warmUp();
135
127
  };
136
- setActiveChunkIndex = async (index) => {
128
+ setActiveChunkIndex = async (index, chunkItemIndex) => {
137
129
  this._activeChunkIndex = index;
138
- this._loadedChunks.forEach((c) => c.setActiveItemIndex(0, false));
139
- await this.populateChunkAtIndex(this._activeChunkIndex + 1, (currentIndex) => currentIndex + 1);
130
+ this.activeChunk.setActiveItemIndex(chunkItemIndex);
140
131
  // Don't wait for warm up to be finished, it runs in the background
141
132
  this.warmUp();
142
133
  };
@@ -148,56 +139,82 @@ export class PlayerChunksManager {
148
139
  return;
149
140
  }
150
141
  if (nextItem.chunkId !== activeChunkId) {
151
- this.setActiveChunkIndex(this.loadedChunks.findIndex((c) => c.model.id === nextItem.chunkId));
152
- this.activeChunk.warmUp();
142
+ const nextChunkIndex = this.loadedChunks.findIndex((c) => c.model.id === nextItem.chunkId);
143
+ if (nextChunkIndex === -1) {
144
+ return;
145
+ }
146
+ const itemIndexInChunk = START_FROM_FIRST_ITEM_ON_CHUNK_SWITCH ? 0 : this.loadedChunks[nextChunkIndex].chunkItems.indexOf(nextItem);
147
+ this.setActiveChunkIndex(nextChunkIndex, itemIndexInChunk);
153
148
  }
154
149
  else {
155
150
  this.activeChunk.setActiveItemIndex(this.activeChunk.chunkItems.indexOf(nextItem));
156
151
  }
157
152
  };
158
153
  warmUp = async () => {
159
- // Early return if manager is sufficient or already loading
160
- if (this._fetchDeferred) {
161
- return this._fetchDeferred.promise;
162
- }
163
- if (this._loadedChunks.length >= this._activeChunkIndex + CHUNKS_BUFFER_SIZE) {
164
- return;
154
+ if (this._warmUpDeferred) {
155
+ return this._warmUpDeferred.promise;
165
156
  }
166
- this._fetchDeferred = new Deferred();
157
+ this._warmUpDeferred = new Deferred();
167
158
  try {
168
- const result = await this.provider.loadMoreChunks();
169
- this._loadedChunks = [
170
- ...this._loadedChunks,
171
- ...result.map((chunk) => new PlayerChunk({
172
- chunk,
173
- provider: { loadChunkItems: this.provider.loadChunkItems }
174
- }))
175
- ];
159
+ await this.warmUpSequentially();
176
160
  }
177
161
  finally {
178
- this._fetchDeferred.resolve();
179
- this._fetchDeferred = null;
162
+ this._warmUpDeferred.resolve();
163
+ this._warmUpDeferred = null;
180
164
  }
181
165
  };
182
- reset = () => {
166
+ reset = async () => {
183
167
  this._activeChunkIndex = -1;
184
168
  this._loadedChunks = [];
185
- this._fetchDeferred = null;
186
- this.warmUp();
169
+ this._warmUpDeferred = null;
170
+ await this.warmUp();
187
171
  };
188
- populateChunkAtIndex = async (index, nextIndexFn) => {
189
- const chunkAtIndex = this._loadedChunks[index];
190
- if (!chunkAtIndex) {
191
- return null;
192
- }
193
- await chunkAtIndex.warmUp();
194
- if (chunkAtIndex.items.length === 0) {
195
- const nextIndex = nextIndexFn(index);
196
- if (nextIndex > index) {
197
- await this.warmUp();
172
+ warmUpSequentially = async () => {
173
+ const startChunkIndex = Math.max(0, this._activeChunkIndex);
174
+ // Calculate how many items we need ahead of current position
175
+ const getItemsAhead = () => {
176
+ const currentFlatIndex = this.flattenedActiveChunkItemIndex;
177
+ const totalItems = this.flattenedChunkItems.length;
178
+ return totalItems - currentFlatIndex - 1; // -1 because current item doesn't count
179
+ };
180
+ while (getItemsAhead() < ITEMS_BUFFER_SIZE) {
181
+ // Find first non-fully-loaded chunk starting from active
182
+ let targetChunkIndex = -1;
183
+ for (let i = startChunkIndex; i < this._loadedChunks.length; i++) {
184
+ if (this._loadedChunks[i].canLoadMore) {
185
+ targetChunkIndex = i;
186
+ break;
187
+ }
188
+ }
189
+ // If all chunks are fully loaded, load more chunks
190
+ if (targetChunkIndex === -1) {
191
+ const result = await this.provider.loadMoreChunks();
192
+ if (result.length === 0) {
193
+ // No more chunks available
194
+ break;
195
+ }
196
+ this._loadedChunks = [
197
+ ...this._loadedChunks,
198
+ ...result.map((chunk) => new PlayerChunk({
199
+ chunk,
200
+ provider: { loadChunkItems: this.provider.loadChunkItems }
201
+ }))
202
+ ];
203
+ continue; // Re-check for chunks to fill
204
+ }
205
+ // Load one page from target chunk
206
+ const chunk = this._loadedChunks[targetChunkIndex];
207
+ const itemsBefore = chunk.items.length;
208
+ await chunk.loadMore();
209
+ const itemsAfter = chunk.items.length;
210
+ // If chunk became fully loaded but added no items, continue to next chunk
211
+ if (itemsAfter === itemsBefore && !chunk.canLoadMore) {
212
+ continue;
213
+ }
214
+ // If no progress made and chunk is not fully loaded, something went wrong
215
+ if (itemsAfter === itemsBefore && chunk.canLoadMore) {
216
+ break; // Avoid infinite loop
198
217
  }
199
- return await this.populateChunkAtIndex(nextIndexFn(index), nextIndexFn);
200
218
  }
201
- return { closestReadyChunkIndex: index };
202
219
  };
203
220
  }
@@ -9,7 +9,11 @@ export class DefaultChunksPlayerBuffer {
9
9
  if (this.loaded.length && this.currentIndex < this.loaded.length - 1) {
10
10
  return true;
11
11
  }
12
- return !this._playerChunksManager.isLoading && !!this._onEndReachedFn;
12
+ // Check if manager is still loading
13
+ if (this._playerChunksManager.isLoading) {
14
+ return false; // Don't trigger onEndReached while loading
15
+ }
16
+ return !!this._onEndReachedFn;
13
17
  });
14
18
  canLoadPrevious = $derived(this.currentIndex > 0);
15
19
  navigationDisabled = $derived(!this.canLoadNext && !this.canLoadPrevious);
@@ -1,9 +1,9 @@
1
1
  import type { PlayerSliderBuffer, PlayerSliderCallbacks } from './types';
2
2
  import { type Snippet } from 'svelte';
3
- declare class __sveltets_Render<T extends {
3
+ declare function $$render<T extends {
4
4
  id: string;
5
- }> {
6
- props(): {
5
+ }>(): {
6
+ props: {
7
7
  buffer: PlayerSliderBuffer<T>;
8
8
  on?: PlayerSliderCallbacks;
9
9
  children: Snippet<[{
@@ -11,8 +11,17 @@ declare class __sveltets_Render<T extends {
11
11
  active?: boolean;
12
12
  }]>;
13
13
  };
14
- events(): {};
15
- slots(): {};
14
+ exports: {};
15
+ bindings: "";
16
+ slots: {};
17
+ events: {};
18
+ };
19
+ declare class __sveltets_Render<T extends {
20
+ id: string;
21
+ }> {
22
+ props(): ReturnType<typeof $$render<T>>['props'];
23
+ events(): ReturnType<typeof $$render<T>>['events'];
24
+ slots(): ReturnType<typeof $$render<T>>['slots'];
16
25
  bindings(): "";
17
26
  exports(): {};
18
27
  }
@@ -284,7 +284,6 @@ const showClassicArrowsAndDots = $derived([SliderMode.ArrowsAndDots, SliderMode.
284
284
  width: 100%;
285
285
  height: 100%;
286
286
  overflow: hidden;
287
- /* Set 'container-type: inline-size;' to reference container*/
288
287
  }
289
288
  .slider__slides {
290
289
  display: flex;
@@ -377,12 +376,14 @@ const showClassicArrowsAndDots = $derived([SliderMode.ArrowsAndDots, SliderMode.
377
376
  text-align: center;
378
377
  color: var(--sc-mc-color--text-white);
379
378
  visibility: hidden;
380
- /* Set 'container-type: inline-size;' to reference container*/
381
379
  }
382
380
  .slider__counts-navigation-button:disabled {
383
381
  opacity: 0.5;
384
382
  cursor: default;
385
383
  }
384
+ .slider__counts-navigation-button {
385
+ /* Set 'container-type: inline-size;' to reference container*/
386
+ }
386
387
  @container (width < 576px) {
387
388
  .slider__counts-navigation-button {
388
389
  visibility: visible;
@@ -411,6 +412,9 @@ const showClassicArrowsAndDots = $derived([SliderMode.ArrowsAndDots, SliderMode.
411
412
  position: static;
412
413
  margin-top: 1rem;
413
414
  }
415
+ .slider {
416
+ /* Set 'container-type: inline-size;' to reference container*/
417
+ }
414
418
  @container (width < 576px) {
415
419
  .slider__navigation-button {
416
420
  visibility: visible;
@@ -1,8 +1,8 @@
1
1
  import type { Locale } from '../../../core/locale';
2
2
  import { type SliderDotsConfig, SliderMode } from './types';
3
3
  import { type Snippet } from 'svelte';
4
- declare class __sveltets_Render<T> {
5
- props(): {
4
+ declare function $$render<T>(): {
5
+ props: {
6
6
  items: T[];
7
7
  initialIndex: number;
8
8
  sliderMode?: SliderMode;
@@ -11,11 +11,18 @@ declare class __sveltets_Render<T> {
11
11
  locale: Locale;
12
12
  on?: {
13
13
  indexChanged: (index: number) => void;
14
- } | undefined;
14
+ };
15
15
  children: Snippet<[T]>;
16
16
  };
17
- events(): {};
18
- slots(): {};
17
+ exports: {};
18
+ bindings: "";
19
+ slots: {};
20
+ events: {};
21
+ };
22
+ declare class __sveltets_Render<T> {
23
+ props(): ReturnType<typeof $$render<T>>['props'];
24
+ events(): ReturnType<typeof $$render<T>>['events'];
25
+ slots(): ReturnType<typeof $$render<T>>['slots'];
19
26
  bindings(): "";
20
27
  exports(): {};
21
28
  }
@@ -51,7 +51,7 @@ const styles = $derived.by(() => {
51
51
  }
52
52
  }
53
53
  :host,
54
- :global([data-theme="default"]) {
54
+ :global([data-theme='default']) {
55
55
  /* Backgrounds */
56
56
  --sc-mc-color--bg-button: #ffffff;
57
57
  --sc-mc-color--bg-card: #ffffff;
@@ -85,7 +85,7 @@ const styles = $derived.by(() => {
85
85
  --sc-mc-color--text-inactive: #e5e7eb;
86
86
  }
87
87
 
88
- :global([data-theme="dark"]) {
88
+ :global([data-theme='dark']) {
89
89
  /* Backgrounds */
90
90
  --sc-mc-color--bg-button: #111827;
91
91
  --sc-mc-color--bg-card: #000000;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@streamscloud/embeddable",
3
- "version": "14.0.1",
3
+ "version": "15.0.0-rc.0",
4
4
  "author": "StreamsCloud",
5
5
  "repository": {
6
6
  "type": "git",
@@ -135,7 +135,7 @@
135
135
  "peerDependencies": {
136
136
  "@fluentui/svg-icons": "^1.1.301",
137
137
  "@popperjs/core": "^2.11.8",
138
- "@streamscloud/streams-analytics-collector": "^2.0.9",
138
+ "@streamscloud/streams-analytics-collector": "^3.0.0",
139
139
  "@urql/core": "^5.1.1",
140
140
  "dequal": "^2.0.3",
141
141
  "dompurify": "^3.2.6",
@@ -1,5 +0,0 @@
1
- /**
2
- * Retrieves the profile ID from localStorage or generates a new one if it doesn't exist
3
- * @returns The profile ID to use for analytics tracking
4
- */
5
- export declare const getOrCreateProfileId: () => string;