Skip to content

Commit 121f4a2

Browse files
committed
wip
1 parent f820bfa commit 121f4a2

File tree

3 files changed

+67
-3
lines changed

3 files changed

+67
-3
lines changed

packages/signals/signals/src/core/buffer/index.ts

Lines changed: 56 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ interface IDBPObjectStoreSignals
2525
'readonly' | 'readwrite' | 'versionchange'
2626
> {}
2727

28+
interface StoreSettings {
29+
maxBufferSize: number
30+
}
2831
export class SignalStoreIndexDB implements SignalPersistentStorage {
2932
static readonly DB_NAME = 'Segment Signals Buffer'
3033
static readonly STORE_NAME = 'signals'
@@ -46,8 +49,8 @@ export class SignalStoreIndexDB implements SignalPersistentStorage {
4649
return store
4750
}
4851

49-
constructor(settings: { maxBufferSize?: number } = {}) {
50-
this.maxBufferSize = settings.maxBufferSize ?? 10
52+
constructor(settings: StoreSettings) {
53+
this.maxBufferSize = settings.maxBufferSize
5154
this.db = this.initSignalDB()
5255
}
5356

@@ -129,6 +132,37 @@ export class SignalStoreIndexDB implements SignalPersistentStorage {
129132
}
130133
}
131134

135+
export class SignalStoreSessionStorage implements SignalPersistentStorage {
136+
private readonly storageKey = 'segment_signals_buffer'
137+
private maxBufferSize: number
138+
139+
constructor(settings: StoreSettings) {
140+
this.maxBufferSize = settings.maxBufferSize
141+
}
142+
143+
add(signal: Signal): void {
144+
const signals = this.getAllSync()
145+
signals.push(signal)
146+
if (signals.length > this.maxBufferSize) {
147+
signals.splice(0, signals.length - this.maxBufferSize)
148+
}
149+
sessionStorage.setItem(this.storageKey, JSON.stringify(signals))
150+
}
151+
152+
getAll(): Promise<Signal[]> {
153+
return Promise.resolve(this.getAllSync())
154+
}
155+
156+
private getAllSync(): Signal[] {
157+
const signals = sessionStorage.getItem(this.storageKey)
158+
return signals ? JSON.parse(signals).reverse() : []
159+
}
160+
161+
clear(): void {
162+
sessionStorage.removeItem(this.storageKey)
163+
}
164+
}
165+
132166
export class SignalBuffer<
133167
T extends SignalPersistentStorage = SignalPersistentStorage
134168
> {
@@ -165,14 +199,33 @@ export class SignalBuffer<
165199
export interface SignalBufferSettingsConfig<
166200
T extends SignalPersistentStorage = SignalPersistentStorage
167201
> {
202+
/**
203+
* Maximum number of signals to store. Only applies if no custom storage implementation is provided.
204+
*/
168205
maxBufferSize?: number
206+
/**
207+
* Choose between sessionStorage and indexDB. Only applies if no custom storage implementation is provided.
208+
* @default 'indexDB'
209+
*/
210+
storageType?: 'session' | 'indexDB'
211+
/**
212+
* Custom storage implementation
213+
* @default SignalStoreIndexDB
214+
*/
169215
signalStorage?: T
170216
}
171217
export const getSignalBuffer = <
172218
T extends SignalPersistentStorage = SignalPersistentStorage
173219
>(
174220
settings: SignalBufferSettingsConfig<T>
175221
) => {
176-
const store = settings.signalStorage ?? new SignalStoreIndexDB(settings)
222+
const settingsWithDefaults: StoreSettings = {
223+
maxBufferSize: 50,
224+
...settings,
225+
}
226+
const store =
227+
settings.signalStorage ?? settings.storageType === 'session'
228+
? new SignalStoreSessionStorage(settingsWithDefaults)
229+
: new SignalStoreIndexDB(settingsWithDefaults)
177230
return new SignalBuffer(store)
178231
}

packages/signals/signals/src/core/signals/settings.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export type SignalsSettingsConfig = Pick<
1919
| 'networkSignalsAllowList'
2020
| 'networkSignalsDisallowList'
2121
| 'networkSignalsAllowSameDomain'
22+
| 'signalStorageType'
2223
> & {
2324
signalStorage?: SignalPersistentStorage
2425
processSignal?: string
@@ -52,6 +53,7 @@ export class SignalGlobalSettings {
5253

5354
this.signalBuffer = {
5455
signalStorage: settings.signalStorage,
56+
storageType: settings.signalStorageType,
5557
maxBufferSize: settings.maxBufferSize,
5658
}
5759
this.ingestClient = {

packages/signals/signals/src/types/settings.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,15 @@ export interface SignalsPluginSettingsConfig {
7272
* Custom signal storage implementation
7373
*/
7474
signalStorage?: SignalStorage | undefined
75+
76+
/**
77+
* Choose between sessionStorage and indexDB.
78+
* IndexDB is more performant and has no size requirements, but signals will be stored across sessions (cleared on new session, but still technically accessible)
79+
* Session storage is cleared on new session, but has a size limit of 5MB.
80+
* Signals are stored in indexDB by default.
81+
* @default 'indexDB'
82+
*/
83+
signalStorageType?: 'session' | 'indexDB' | undefined
7584
}
7685

7786
export type RegexLike = RegExp | string

0 commit comments

Comments
 (0)