a0-purchases
Version:
Lightweight subscription management for AI apps with auto-detecting providers
129 lines • 4.17 kB
JavaScript
class CommerceStateManager {
constructor() {
this.state = {
isInitialized: false,
isInitializing: false,
userId: null,
offerings: { all: {}, current: null },
customerInfo: null,
storeProducts: [],
isPurchasing: false,
isRestoring: false,
lastError: null,
};
this.listeners = new Set();
}
// Read-only state access
getState() {
return Object.assign({}, this.state);
}
// Selective getters for common use cases
getCustomerInfo() {
return this.state.customerInfo;
}
getOfferings() {
return this.state.offerings;
}
getUserId() {
return this.state.userId;
}
getStoreProducts() {
return [...this.state.storeProducts];
}
isReady() {
return this.state.isInitialized;
}
isPremium() {
var _a, _b;
return Boolean(((_b = (_a = this.state.customerInfo) === null || _a === void 0 ? void 0 : _a.entitlements) === null || _b === void 0 ? void 0 : _b.active) &&
Object.keys(this.state.customerInfo.entitlements.active).length > 0);
}
// State mutations (package-private)
_updateState(partial) {
const oldState = this.state;
this.state = Object.assign(Object.assign({}, oldState), partial);
// Notify listeners if state actually changed
if (this._hasStateChanged(oldState, this.state)) {
this._notifyListeners();
}
}
_setUserId(userId) {
this._updateState({ userId });
}
_setCustomerInfo(customerInfo) {
this._updateState({ customerInfo });
}
_setOfferings(offerings) {
this._updateState({ offerings });
}
_setStoreProducts(storeProducts) {
this._updateState({ storeProducts });
}
_setInitialized(isInitialized) {
this._updateState({
isInitialized,
isInitializing: false,
lastError: isInitialized ? null : this.state.lastError
});
}
_setInitializing(isInitializing) {
this._updateState({ isInitializing });
}
_setPurchasing(isPurchasing) {
this._updateState({ isPurchasing });
}
_setRestoring(isRestoring) {
this._updateState({ isRestoring });
}
_setError(error) {
this._updateState({ lastError: error });
}
_reset() {
this.state = {
isInitialized: false,
isInitializing: false,
userId: null,
offerings: { all: {}, current: null },
customerInfo: null,
storeProducts: [],
isPurchasing: false,
isRestoring: false,
lastError: null,
};
this._notifyListeners();
}
// Subscription management
subscribe(listener) {
this.listeners.add(listener);
// Return unsubscribe function
return () => {
this.listeners.delete(listener);
};
}
_notifyListeners() {
const currentState = this.getState();
this.listeners.forEach(listener => {
try {
listener(currentState);
}
catch (error) {
console.warn('[CommerceState] Listener error:', error);
}
});
}
_hasStateChanged(oldState, newState) {
// Shallow comparison for most fields, deep comparison for objects
return (oldState.isInitialized !== newState.isInitialized ||
oldState.isInitializing !== newState.isInitializing ||
oldState.userId !== newState.userId ||
oldState.customerInfo !== newState.customerInfo ||
oldState.offerings !== newState.offerings ||
oldState.storeProducts.length !== newState.storeProducts.length ||
oldState.isPurchasing !== newState.isPurchasing ||
oldState.isRestoring !== newState.isRestoring ||
oldState.lastError !== newState.lastError);
}
}
// Export singleton instance
export const commerceState = new CommerceStateManager();
//# sourceMappingURL=commerceState.js.map