@schematichq/schematic-angular 1.4.0 → 1.5.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.
package/README.md CHANGED
@@ -229,6 +229,44 @@ export class PlanComponent {
229
229
  }
230
230
  ```
231
231
 
232
+ ### Credit balances
233
+
234
+ Use `creditBalance$` to observe a company's credit balance. It is keyed by credit ID and emits as the balance changes over the DataStream:
235
+
236
+ ```typescript
237
+ import { Component, inject } from "@angular/core";
238
+ import { AsyncPipe } from "@angular/common";
239
+ import { SchematicService } from "@schematichq/schematic-angular";
240
+
241
+ @Component({
242
+ selector: "app-credit-meter",
243
+ standalone: true,
244
+ imports: [AsyncPipe],
245
+ template: `
246
+ @if (creditBalance$ | async; as credit) {
247
+ @if (credit.isLoading) {
248
+ <div>Loading…</div>
249
+ } @else {
250
+ <div>{{ credit.balance }} credits remaining</div>
251
+ }
252
+ }
253
+ `,
254
+ })
255
+ export class CreditMeterComponent {
256
+ private schematic = inject(SchematicService);
257
+ creditBalance$ = this.schematic.creditBalance$("credit-id");
258
+ }
259
+ ```
260
+
261
+ `creditBalance$` emits an object with the following properties:
262
+
263
+ | Property | Type | Description |
264
+ | --- | --- | --- |
265
+ | `balance` | `number` | The spendable balance, or `0` while loading or when the company holds no balance in this credit |
266
+ | `isLoading` | `boolean` | `true` while the balance is still loading and no value has arrived yet |
267
+
268
+ It surfaces the `settled` (spendable) balance. The credit ID is available on a feature's entitlement: `entitlement$(key)` emits `creditId` for credit-based features.
269
+
232
270
  ## API Reference
233
271
 
234
272
  ### `provideSchematic(config)`
@@ -248,6 +286,7 @@ Injectable service providing all Schematic functionality:
248
286
  | `flagValue$(key, fallback?)` | `Observable<boolean>` | Observe a feature flag's boolean value |
249
287
  | `entitlement$(key, fallback?)` | `Observable<CheckFlagReturn>` | Observe detailed entitlement data |
250
288
  | `plan$()` | `Observable<CheckPlanReturn \| undefined>` | Observe plan information |
289
+ | `creditBalance$(creditId)` | `Observable<SchematicCreditBalance>` | Observe a company's lease-aware credit balance |
251
290
  | `isPending$()` | `Observable<boolean>` | Observe loading state |
252
291
 
253
292
  ### `SCHEMATIC_CLIENT`
@@ -28,6 +28,7 @@ class SchematicService {
28
28
  client = inject(SCHEMATIC_CLIENT);
29
29
  flagValueCache = new Map();
30
30
  entitlementCache = new Map();
31
+ creditBalanceCache = new Map();
31
32
  planCache;
32
33
  isPendingCache;
33
34
  getClient() {
@@ -95,6 +96,40 @@ class SchematicService {
95
96
  }));
96
97
  return this.planCache;
97
98
  }
99
+ /**
100
+ * Observe a company's live, lease-aware credit balance for a single credit type.
101
+ *
102
+ * Surfaces the spendable `settled` balance, sourced from the streamed credit
103
+ * balances map (keyed by credit ID). It emits as partials arrive over the
104
+ * DataStream, so it stays accurate during an open lease — when the raw
105
+ * `remaining` would otherwise read stale / falsely "exhausted".
106
+ *
107
+ * The credit ID is available on a feature's entitlement: `entitlement$(key)`
108
+ * emits `creditId` for credit-based features.
109
+ */
110
+ creditBalance$(creditId) {
111
+ let cached = this.creditBalanceCache.get(creditId);
112
+ if (cached)
113
+ return cached;
114
+ cached = new Observable((subscriber) => {
115
+ const emit = () => {
116
+ const balance = this.client.getCreditBalance(creditId);
117
+ subscriber.next({
118
+ balance: balance?.settled ?? 0,
119
+ isLoading: balance === undefined && this.client.getIsPending(),
120
+ });
121
+ };
122
+ emit();
123
+ const unsubscribeBalance = this.client.addCreditBalanceListener(() => emit());
124
+ const unsubscribePending = this.client.addIsPendingListener(() => emit());
125
+ return () => {
126
+ unsubscribeBalance();
127
+ unsubscribePending();
128
+ };
129
+ }).pipe(distinctUntilChanged(shallowEqual), shareReplay({ bufferSize: 1, refCount: true }), finalize(() => this.creditBalanceCache.delete(creditId)));
130
+ this.creditBalanceCache.set(creditId, cached);
131
+ return cached;
132
+ }
98
133
  isPending$() {
99
134
  if (this.isPendingCache)
100
135
  return this.isPendingCache;
@@ -109,14 +144,14 @@ class SchematicService {
109
144
  }));
110
145
  return this.isPendingCache;
111
146
  }
112
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: SchematicService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
113
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: SchematicService });
147
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SchematicService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
148
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SchematicService });
114
149
  }
115
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: SchematicService, decorators: [{
150
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SchematicService, decorators: [{
116
151
  type: Injectable
117
152
  }] });
118
153
 
119
- const version = "1.4.0";
154
+ const version = "1.5.0";
120
155
 
121
156
  function provideSchematic(config) {
122
157
  const { client: providedClient, publishableKey, additionalHeaders, ...restOpts } = config;
@@ -1 +1 @@
1
- {"version":3,"file":"schematichq-schematic-angular.mjs","sources":["../../src/token.ts","../../src/schematic.service.ts","../../src/version.ts","../../src/provide.ts","../../src/schematichq-schematic-angular.ts"],"sourcesContent":["import { InjectionToken } from \"@angular/core\";\nimport * as SchematicJS from \"@schematichq/schematic-js\";\n\nexport const SCHEMATIC_CLIENT = new InjectionToken<SchematicJS.Schematic>(\n \"SchematicClient\",\n);\n","import { Injectable, inject } from \"@angular/core\";\nimport * as SchematicJS from \"@schematichq/schematic-js\";\nimport { Observable, distinctUntilChanged, finalize, shareReplay } from \"rxjs\";\nimport { SCHEMATIC_CLIENT } from \"./token\";\n\nfunction shallowEqual<T extends Record<string, unknown>>(\n a: T | undefined,\n b: T | undefined,\n): boolean {\n if (a === b) return true;\n if (!a || !b) return false;\n const keysA = Object.keys(a);\n const keysB = Object.keys(b);\n if (keysA.length !== keysB.length) return false;\n return keysA.every((key) => {\n const valA = a[key];\n const valB = b[key];\n if (valA instanceof Date && valB instanceof Date) {\n return valA.getTime() === valB.getTime();\n }\n return valA === valB;\n });\n}\n\n@Injectable()\nexport class SchematicService {\n private client = inject(SCHEMATIC_CLIENT);\n\n private flagValueCache = new Map<string, Observable<boolean>>();\n private entitlementCache = new Map<\n string,\n Observable<SchematicJS.CheckFlagReturn>\n >();\n private planCache?: Observable<SchematicJS.CheckPlanReturn | undefined>;\n private isPendingCache?: Observable<boolean>;\n\n getClient(): SchematicJS.Schematic {\n return this.client;\n }\n\n setContext(context: SchematicJS.SchematicContext): void {\n this.client.setContext(context);\n }\n\n identify(body: SchematicJS.EventBodyIdentify): void {\n this.client.identify(body);\n }\n\n track(body: SchematicJS.EventBodyTrack): void {\n this.client.track(body);\n }\n\n flagValue$(key: string, fallback: boolean = false): Observable<boolean> {\n const cacheKey = `${key}:${fallback}`;\n let cached = this.flagValueCache.get(cacheKey);\n if (cached) return cached;\n\n cached = new Observable<boolean>((subscriber) => {\n const current = this.client.getFlagValue(key);\n subscriber.next(current ?? fallback);\n\n const unsubscribe = this.client.addFlagValueListener(key, () => {\n const value = this.client.getFlagValue(key);\n subscriber.next(value ?? fallback);\n });\n\n return () => unsubscribe();\n }).pipe(\n distinctUntilChanged(),\n shareReplay({ bufferSize: 1, refCount: true }),\n finalize(() => this.flagValueCache.delete(cacheKey)),\n );\n\n this.flagValueCache.set(cacheKey, cached);\n return cached;\n }\n\n entitlement$(\n key: string,\n fallback: boolean = false,\n ): Observable<SchematicJS.CheckFlagReturn> {\n const cacheKey = `${key}:${fallback}`;\n let cached = this.entitlementCache.get(cacheKey);\n if (cached) return cached;\n\n const fallbackCheck: SchematicJS.CheckFlagReturn = {\n flag: key,\n reason: \"Fallback\",\n value: fallback,\n };\n\n cached = new Observable<SchematicJS.CheckFlagReturn>((subscriber) => {\n const current = this.client.getFlagCheck(key);\n subscriber.next(current ?? fallbackCheck);\n\n const unsubscribe = this.client.addFlagCheckListener(key, () => {\n const check = this.client.getFlagCheck(key);\n subscriber.next(check ?? fallbackCheck);\n });\n\n return () => unsubscribe();\n }).pipe(\n distinctUntilChanged(shallowEqual),\n shareReplay({ bufferSize: 1, refCount: true }),\n finalize(() => this.entitlementCache.delete(cacheKey)),\n );\n\n this.entitlementCache.set(cacheKey, cached);\n return cached;\n }\n\n plan$(): Observable<SchematicJS.CheckPlanReturn | undefined> {\n if (this.planCache) return this.planCache;\n\n this.planCache = new Observable<SchematicJS.CheckPlanReturn | undefined>(\n (subscriber) => {\n subscriber.next(this.client.getPlan());\n\n const unsubscribe = this.client.addPlanListener(() => {\n subscriber.next(this.client.getPlan());\n });\n\n return () => unsubscribe();\n },\n ).pipe(\n distinctUntilChanged(shallowEqual),\n shareReplay({ bufferSize: 1, refCount: true }),\n finalize(() => {\n this.planCache = undefined;\n }),\n );\n\n return this.planCache;\n }\n\n isPending$(): Observable<boolean> {\n if (this.isPendingCache) return this.isPendingCache;\n\n this.isPendingCache = new Observable<boolean>((subscriber) => {\n subscriber.next(this.client.getIsPending());\n\n const unsubscribe = this.client.addIsPendingListener(() => {\n subscriber.next(this.client.getIsPending());\n });\n\n return () => unsubscribe();\n }).pipe(\n distinctUntilChanged(),\n shareReplay({ bufferSize: 1, refCount: true }),\n finalize(() => {\n this.isPendingCache = undefined;\n }),\n );\n\n return this.isPendingCache;\n }\n}\n","export const version = \"1.4.0\";\n","import { DestroyRef, inject, makeEnvironmentProviders } from \"@angular/core\";\nimport * as SchematicJS from \"@schematichq/schematic-js\";\n\nimport { SchematicService } from \"./schematic.service\";\nimport { SCHEMATIC_CLIENT } from \"./token\";\nimport { version } from \"./version\";\n\ntype BaseSchematicConfig = Omit<SchematicJS.SchematicOptions, \"useWebSocket\">;\n\ntype SchematicConfigWithClient = BaseSchematicConfig & {\n client: SchematicJS.Schematic;\n publishableKey?: never;\n};\n\ntype SchematicConfigWithKey = BaseSchematicConfig & {\n client?: never;\n publishableKey: string;\n};\n\nexport type SchematicConfig =\n | SchematicConfigWithClient\n | SchematicConfigWithKey;\n\nexport function provideSchematic(config: SchematicConfig) {\n const {\n client: providedClient,\n publishableKey,\n additionalHeaders,\n ...restOpts\n } = config;\n\n return makeEnvironmentProviders([\n {\n provide: SCHEMATIC_CLIENT,\n useFactory: () => {\n const isProvidedClient = !!providedClient;\n\n const client = isProvidedClient\n ? providedClient\n : new SchematicJS.Schematic(publishableKey!, {\n ...restOpts,\n useWebSocket: true,\n additionalHeaders: {\n \"X-Schematic-Client-Version\": `schematic-angular@${version}`,\n ...additionalHeaders,\n },\n });\n\n const destroyRef = inject(DestroyRef);\n destroyRef.onDestroy(() => {\n if (!isProvidedClient) {\n client.cleanup().catch((error: unknown) => {\n console.error(\"Error during Schematic cleanup:\", error);\n });\n }\n });\n\n return client;\n },\n },\n SchematicService,\n ]);\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"schematichq-schematic-angular.mjs","sources":["../../src/token.ts","../../src/schematic.service.ts","../../src/version.ts","../../src/provide.ts","../../src/schematichq-schematic-angular.ts"],"sourcesContent":["import { InjectionToken } from \"@angular/core\";\nimport * as SchematicJS from \"@schematichq/schematic-js\";\n\nexport const SCHEMATIC_CLIENT = new InjectionToken<SchematicJS.Schematic>(\n \"SchematicClient\",\n);\n","import { Injectable, inject } from \"@angular/core\";\nimport * as SchematicJS from \"@schematichq/schematic-js\";\nimport { Observable, distinctUntilChanged, finalize, shareReplay } from \"rxjs\";\nimport { SCHEMATIC_CLIENT } from \"./token\";\n\n/** A company's credit balance for a single credit type, plus a loading flag */\nexport type SchematicCreditBalance = {\n /** The spendable balance; 0 while loading or when the company holds no balance in this credit */\n balance: number;\n /** True while the balance is still loading and no value has arrived yet */\n isLoading: boolean;\n};\n\nfunction shallowEqual<T extends Record<string, unknown>>(\n a: T | undefined,\n b: T | undefined,\n): boolean {\n if (a === b) return true;\n if (!a || !b) return false;\n const keysA = Object.keys(a);\n const keysB = Object.keys(b);\n if (keysA.length !== keysB.length) return false;\n return keysA.every((key) => {\n const valA = a[key];\n const valB = b[key];\n if (valA instanceof Date && valB instanceof Date) {\n return valA.getTime() === valB.getTime();\n }\n return valA === valB;\n });\n}\n\n@Injectable()\nexport class SchematicService {\n private client = inject(SCHEMATIC_CLIENT);\n\n private flagValueCache = new Map<string, Observable<boolean>>();\n private entitlementCache = new Map<\n string,\n Observable<SchematicJS.CheckFlagReturn>\n >();\n private creditBalanceCache = new Map<\n string,\n Observable<SchematicCreditBalance>\n >();\n private planCache?: Observable<SchematicJS.CheckPlanReturn | undefined>;\n private isPendingCache?: Observable<boolean>;\n\n getClient(): SchematicJS.Schematic {\n return this.client;\n }\n\n setContext(context: SchematicJS.SchematicContext): void {\n this.client.setContext(context);\n }\n\n identify(body: SchematicJS.EventBodyIdentify): void {\n this.client.identify(body);\n }\n\n track(body: SchematicJS.EventBodyTrack): void {\n this.client.track(body);\n }\n\n flagValue$(key: string, fallback: boolean = false): Observable<boolean> {\n const cacheKey = `${key}:${fallback}`;\n let cached = this.flagValueCache.get(cacheKey);\n if (cached) return cached;\n\n cached = new Observable<boolean>((subscriber) => {\n const current = this.client.getFlagValue(key);\n subscriber.next(current ?? fallback);\n\n const unsubscribe = this.client.addFlagValueListener(key, () => {\n const value = this.client.getFlagValue(key);\n subscriber.next(value ?? fallback);\n });\n\n return () => unsubscribe();\n }).pipe(\n distinctUntilChanged(),\n shareReplay({ bufferSize: 1, refCount: true }),\n finalize(() => this.flagValueCache.delete(cacheKey)),\n );\n\n this.flagValueCache.set(cacheKey, cached);\n return cached;\n }\n\n entitlement$(\n key: string,\n fallback: boolean = false,\n ): Observable<SchematicJS.CheckFlagReturn> {\n const cacheKey = `${key}:${fallback}`;\n let cached = this.entitlementCache.get(cacheKey);\n if (cached) return cached;\n\n const fallbackCheck: SchematicJS.CheckFlagReturn = {\n flag: key,\n reason: \"Fallback\",\n value: fallback,\n };\n\n cached = new Observable<SchematicJS.CheckFlagReturn>((subscriber) => {\n const current = this.client.getFlagCheck(key);\n subscriber.next(current ?? fallbackCheck);\n\n const unsubscribe = this.client.addFlagCheckListener(key, () => {\n const check = this.client.getFlagCheck(key);\n subscriber.next(check ?? fallbackCheck);\n });\n\n return () => unsubscribe();\n }).pipe(\n distinctUntilChanged(shallowEqual),\n shareReplay({ bufferSize: 1, refCount: true }),\n finalize(() => this.entitlementCache.delete(cacheKey)),\n );\n\n this.entitlementCache.set(cacheKey, cached);\n return cached;\n }\n\n plan$(): Observable<SchematicJS.CheckPlanReturn | undefined> {\n if (this.planCache) return this.planCache;\n\n this.planCache = new Observable<SchematicJS.CheckPlanReturn | undefined>(\n (subscriber) => {\n subscriber.next(this.client.getPlan());\n\n const unsubscribe = this.client.addPlanListener(() => {\n subscriber.next(this.client.getPlan());\n });\n\n return () => unsubscribe();\n },\n ).pipe(\n distinctUntilChanged(shallowEqual),\n shareReplay({ bufferSize: 1, refCount: true }),\n finalize(() => {\n this.planCache = undefined;\n }),\n );\n\n return this.planCache;\n }\n\n /**\n * Observe a company's live, lease-aware credit balance for a single credit type.\n *\n * Surfaces the spendable `settled` balance, sourced from the streamed credit\n * balances map (keyed by credit ID). It emits as partials arrive over the\n * DataStream, so it stays accurate during an open lease — when the raw\n * `remaining` would otherwise read stale / falsely \"exhausted\".\n *\n * The credit ID is available on a feature's entitlement: `entitlement$(key)`\n * emits `creditId` for credit-based features.\n */\n creditBalance$(creditId: string): Observable<SchematicCreditBalance> {\n let cached = this.creditBalanceCache.get(creditId);\n if (cached) return cached;\n\n cached = new Observable<SchematicCreditBalance>((subscriber) => {\n const emit = () => {\n const balance = this.client.getCreditBalance(creditId);\n subscriber.next({\n balance: balance?.settled ?? 0,\n isLoading: balance === undefined && this.client.getIsPending(),\n });\n };\n\n emit();\n\n const unsubscribeBalance = this.client.addCreditBalanceListener(() =>\n emit(),\n );\n const unsubscribePending = this.client.addIsPendingListener(() => emit());\n\n return () => {\n unsubscribeBalance();\n unsubscribePending();\n };\n }).pipe(\n distinctUntilChanged(shallowEqual),\n shareReplay({ bufferSize: 1, refCount: true }),\n finalize(() => this.creditBalanceCache.delete(creditId)),\n );\n\n this.creditBalanceCache.set(creditId, cached);\n return cached;\n }\n\n isPending$(): Observable<boolean> {\n if (this.isPendingCache) return this.isPendingCache;\n\n this.isPendingCache = new Observable<boolean>((subscriber) => {\n subscriber.next(this.client.getIsPending());\n\n const unsubscribe = this.client.addIsPendingListener(() => {\n subscriber.next(this.client.getIsPending());\n });\n\n return () => unsubscribe();\n }).pipe(\n distinctUntilChanged(),\n shareReplay({ bufferSize: 1, refCount: true }),\n finalize(() => {\n this.isPendingCache = undefined;\n }),\n );\n\n return this.isPendingCache;\n }\n}\n","export const version = \"1.5.0\";\n","import { DestroyRef, inject, makeEnvironmentProviders } from \"@angular/core\";\nimport * as SchematicJS from \"@schematichq/schematic-js\";\n\nimport { SchematicService } from \"./schematic.service\";\nimport { SCHEMATIC_CLIENT } from \"./token\";\nimport { version } from \"./version\";\n\ntype BaseSchematicConfig = Omit<SchematicJS.SchematicOptions, \"useWebSocket\">;\n\ntype SchematicConfigWithClient = BaseSchematicConfig & {\n client: SchematicJS.Schematic;\n publishableKey?: never;\n};\n\ntype SchematicConfigWithKey = BaseSchematicConfig & {\n client?: never;\n publishableKey: string;\n};\n\nexport type SchematicConfig =\n | SchematicConfigWithClient\n | SchematicConfigWithKey;\n\nexport function provideSchematic(config: SchematicConfig) {\n const {\n client: providedClient,\n publishableKey,\n additionalHeaders,\n ...restOpts\n } = config;\n\n return makeEnvironmentProviders([\n {\n provide: SCHEMATIC_CLIENT,\n useFactory: () => {\n const isProvidedClient = !!providedClient;\n\n const client = isProvidedClient\n ? providedClient\n : new SchematicJS.Schematic(publishableKey!, {\n ...restOpts,\n useWebSocket: true,\n additionalHeaders: {\n \"X-Schematic-Client-Version\": `schematic-angular@${version}`,\n ...additionalHeaders,\n },\n });\n\n const destroyRef = inject(DestroyRef);\n destroyRef.onDestroy(() => {\n if (!isProvidedClient) {\n client.cleanup().catch((error: unknown) => {\n console.error(\"Error during Schematic cleanup:\", error);\n });\n }\n });\n\n return client;\n },\n },\n SchematicService,\n ]);\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,18 +1,24 @@
1
1
  {
2
2
  "name": "@schematichq/schematic-angular",
3
- "version": "1.4.0",
3
+ "version": "1.5.0",
4
4
  "author": "Schematic <engineering@schematichq.com>",
5
5
  "license": "MIT",
6
6
  "repository": {
7
7
  "type": "git",
8
8
  "url": "git+ssh://git@github.com/SchematicHQ/schematic-js.git"
9
9
  },
10
+ "dependencies": {
11
+ "@schematichq/schematic-js": "^1.5.0",
12
+ "tslib": "^2.3.0"
13
+ },
10
14
  "peerDependencies": {
11
15
  "@angular/core": ">=19.0.0",
12
16
  "rxjs": ">=7.0.0"
13
17
  },
14
18
  "resolutions": {
15
- "minimatch": ">=3.1.3"
19
+ "minimatch": ">=3.1.3",
20
+ "esbuild": ">=0.28.1",
21
+ "@babel/core": "^7.29.6"
16
22
  },
17
23
  "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e",
18
24
  "module": "fesm2022/schematichq-schematic-angular.mjs",
@@ -27,8 +33,5 @@
27
33
  }
28
34
  },
29
35
  "sideEffects": false,
30
- "type": "module",
31
- "dependencies": {
32
- "tslib": "^2.3.0"
33
- }
36
+ "type": "module"
34
37
  }
@@ -1,7 +1,7 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { InjectionToken } from '@angular/core';
3
3
  import * as SchematicJS from '@schematichq/schematic-js';
4
- export { CheckFlagReturn, CheckPlanReturn, Event, EventBody, EventBodyIdentify, EventBodyTrack, EventType, Keys, RuleType, Schematic, SchematicContext, SchematicOptions, StoragePersister, Traits, TrialStatus, UsagePeriod } from '@schematichq/schematic-js';
4
+ export { CheckFlagReturn, CheckPlanReturn, CompanyCreditBalance, CreditBalance, CreditBalances, Event, EventBody, EventBodyIdentify, EventBodyTrack, EventType, Keys, RuleType, Schematic, SchematicContext, SchematicOptions, StoragePersister, Traits, TrialStatus, UsagePeriod } from '@schematichq/schematic-js';
5
5
  import { Observable } from 'rxjs';
6
6
 
7
7
  type BaseSchematicConfig = Omit<SchematicJS.SchematicOptions, "useWebSocket">;
@@ -18,10 +18,18 @@ declare function provideSchematic(config: SchematicConfig): i0.EnvironmentProvid
18
18
 
19
19
  declare const SCHEMATIC_CLIENT: InjectionToken<SchematicJS.Schematic>;
20
20
 
21
+ /** A company's credit balance for a single credit type, plus a loading flag */
22
+ type SchematicCreditBalance = {
23
+ /** The spendable balance; 0 while loading or when the company holds no balance in this credit */
24
+ balance: number;
25
+ /** True while the balance is still loading and no value has arrived yet */
26
+ isLoading: boolean;
27
+ };
21
28
  declare class SchematicService {
22
29
  private client;
23
30
  private flagValueCache;
24
31
  private entitlementCache;
32
+ private creditBalanceCache;
25
33
  private planCache?;
26
34
  private isPendingCache?;
27
35
  getClient(): SchematicJS.Schematic;
@@ -31,10 +39,22 @@ declare class SchematicService {
31
39
  flagValue$(key: string, fallback?: boolean): Observable<boolean>;
32
40
  entitlement$(key: string, fallback?: boolean): Observable<SchematicJS.CheckFlagReturn>;
33
41
  plan$(): Observable<SchematicJS.CheckPlanReturn | undefined>;
42
+ /**
43
+ * Observe a company's live, lease-aware credit balance for a single credit type.
44
+ *
45
+ * Surfaces the spendable `settled` balance, sourced from the streamed credit
46
+ * balances map (keyed by credit ID). It emits as partials arrive over the
47
+ * DataStream, so it stays accurate during an open lease — when the raw
48
+ * `remaining` would otherwise read stale / falsely "exhausted".
49
+ *
50
+ * The credit ID is available on a feature's entitlement: `entitlement$(key)`
51
+ * emits `creditId` for credit-based features.
52
+ */
53
+ creditBalance$(creditId: string): Observable<SchematicCreditBalance>;
34
54
  isPending$(): Observable<boolean>;
35
55
  static ɵfac: i0.ɵɵFactoryDeclaration<SchematicService, never>;
36
56
  static ɵprov: i0.ɵɵInjectableDeclaration<SchematicService>;
37
57
  }
38
58
 
39
59
  export { SCHEMATIC_CLIENT, SchematicService, provideSchematic };
40
- export type { SchematicConfig };
60
+ export type { SchematicConfig, SchematicCreditBalance };