@plyaz/core 1.8.1 → 1.8.3

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.
@@ -2391,10 +2391,16 @@ var init_ServiceRegistry = __esm({
2391
2391
  return initPromise;
2392
2392
  }
2393
2393
  /** Build stores for service injection */
2394
- static buildStoresForService(config) {
2394
+ // eslint-disable-next-line complexity
2395
+ static buildStoresForService(config, entry) {
2395
2396
  const allKeys = /* @__PURE__ */ new Set();
2396
2397
  if (config.store) {
2397
2398
  allKeys.add(config.store);
2399
+ } else if ("primaryStoreKey" in entry.service && typeof entry.service.primaryStoreKey === "string") {
2400
+ allKeys.add(entry.service.primaryStoreKey);
2401
+ _ServiceRegistry.logger.debug(
2402
+ `Auto-resolved store key '${entry.service.primaryStoreKey}' from service class`
2403
+ );
2398
2404
  }
2399
2405
  if (config.readStores) {
2400
2406
  config.readStores.forEach((key) => allKeys.add(key));
@@ -2432,7 +2438,7 @@ var init_ServiceRegistry = __esm({
2432
2438
  const observability = _ServiceRegistry.buildObservabilityConfig(config, entry);
2433
2439
  const storage = await _ServiceRegistry.buildStorageConfig(config, entry);
2434
2440
  const notifications = await _ServiceRegistry.buildNotificationsConfig(config, entry);
2435
- const stores = _ServiceRegistry.buildStoresForService(config);
2441
+ const stores = _ServiceRegistry.buildStoresForService(config, entry);
2436
2442
  let observabilityInstance = observability?.instance;
2437
2443
  if (observability?.dedicated && observability.config) {
2438
2444
  observabilityInstance = await _ServiceRegistry.createDedicatedObservability(
@@ -3983,6 +3989,13 @@ var init_CoreInitializer = __esm({
3983
3989
  /** Create fetch flags function */
3984
3990
  static createFetchFlagsFn(config, verbose) {
3985
3991
  return async () => {
3992
+ if (config?.provider !== "api") {
3993
+ _Core.log(
3994
+ `Feature flags using ${config?.provider ?? "default"} provider (no API fetch)`,
3995
+ verbose
3996
+ );
3997
+ return config?.defaults ?? {};
3998
+ }
3986
3999
  try {
3987
4000
  const client = ApiClientService.getClient();
3988
4001
  const endpoint = config?.apiEndpoint ?? "/feature-flags";
@@ -4002,6 +4015,7 @@ var init_CoreInitializer = __esm({
4002
4015
  /**
4003
4016
  * Initialize feature flags slice within root store
4004
4017
  */
4018
+ // eslint-disable-next-line complexity
4005
4019
  static async initializeFeatureFlags(config, verbose) {
4006
4020
  if (config?.enabled === false) {
4007
4021
  _Core.log("Feature flags disabled by configuration", verbose);
@@ -4014,11 +4028,16 @@ var init_CoreInitializer = __esm({
4014
4028
  );
4015
4029
  }
4016
4030
  _Core._flagConfig = config ?? {};
4017
- _Core.log("Initializing feature flags from root store...", verbose);
4031
+ const isApiProvider = config?.provider === "api";
4032
+ _Core.log(
4033
+ `Initializing feature flags from root store (provider: ${config?.provider ?? "default"})...`,
4034
+ verbose
4035
+ );
4018
4036
  const state = _Core._rootStore.getState();
4019
4037
  await state.featureFlags.initialize({
4020
4038
  defaults: _Core._flagConfig.defaults,
4021
- polling: _Core._flagConfig.polling,
4039
+ // Only enable polling for API provider
4040
+ polling: isApiProvider ? _Core._flagConfig.polling : void 0,
4022
4041
  fetchFn: _Core.createFetchFlagsFn(_Core._flagConfig, verbose),
4023
4042
  onFlagChange: _Core._flagConfig.onFlagChange,
4024
4043
  onError: _Core._flagConfig.onError
@@ -4439,13 +4458,14 @@ var init_BaseFrontendDomainService = __esm({
4439
4458
  init_BaseDomainService();
4440
4459
  init_CoreEventManager();
4441
4460
  init_CoreInitializer();
4442
- BaseFrontendDomainService = class extends BaseDomainService {
4461
+ BaseFrontendDomainService = class _BaseFrontendDomainService extends BaseDomainService {
4443
4462
  // ─────────────────────────────────────────────────────────────────────────
4444
4463
  // Constructor
4445
4464
  // ─────────────────────────────────────────────────────────────────────────
4446
4465
  // eslint-disable-next-line complexity
4447
4466
  constructor(config) {
4448
- super(config);
4467
+ const resolvedConfig = _BaseFrontendDomainService.resolveApiClientConfig(config);
4468
+ super(resolvedConfig);
4449
4469
  // ─────────────────────────────────────────────────────────────────────────
4450
4470
  // Store Properties
4451
4471
  // ─────────────────────────────────────────────────────────────────────────
@@ -4471,6 +4491,11 @@ var init_BaseFrontendDomainService = __esm({
4471
4491
  const serviceConfig = config.serviceConfig;
4472
4492
  if (serviceConfig.store !== void 0) {
4473
4493
  this.primaryStoreKey = serviceConfig.store;
4494
+ } else {
4495
+ const staticKey = this.constructor.primaryStoreKey;
4496
+ if (staticKey) {
4497
+ this.primaryStoreKey = staticKey;
4498
+ }
4474
4499
  }
4475
4500
  if (serviceConfig.readStores !== void 0) {
4476
4501
  this.readStoreKeys = Array.from(
@@ -4489,9 +4514,12 @@ var init_BaseFrontendDomainService = __esm({
4489
4514
  this._primaryStore = primaryStore;
4490
4515
  this.logDebug(`Connected primary store: '${this.primaryStoreKey}'`);
4491
4516
  } else {
4492
- this.logWarn(
4493
- `Primary store '${this.primaryStoreKey}' not found. Store mutations (setData/updateData/setLoading) will be disabled. Configure stores in PlyazProvider to enable store integration.`
4494
- );
4517
+ const isServer = typeof globalThis.window === "undefined";
4518
+ if (!isServer) {
4519
+ this.logWarn(
4520
+ `Primary store '${this.primaryStoreKey}' not found. Store mutations (setData/updateData/setLoading) will be disabled. Configure stores in PlyazProvider to enable store integration.`
4521
+ );
4522
+ }
4495
4523
  }
4496
4524
  }
4497
4525
  for (const key of this.readStoreKeys) {
@@ -4516,6 +4544,66 @@ var init_BaseFrontendDomainService = __esm({
4516
4544
  static {
4517
4545
  __name(this, "BaseFrontendDomainService");
4518
4546
  }
4547
+ /**
4548
+ * Auto-resolve apiClientConfig from serviceConfig.apiBasePath if not explicitly provided.
4549
+ * This reduces boilerplate in child services - they only need to set apiBasePath in config.
4550
+ *
4551
+ * Priority:
4552
+ * 1. Explicit apiClientConfig.baseURL (full control)
4553
+ * 2. serviceConfig.apiBasePath (auto-constructed, merged with injected options)
4554
+ * 3. undefined (no API client)
4555
+ *
4556
+ * When auto-constructing, merges injected API options (headers, timeout, etc.)
4557
+ * with the service's apiBasePath as baseURL.
4558
+ */
4559
+ static resolveApiClientConfig(config) {
4560
+ if (config.apiClientConfig?.baseURL) {
4561
+ return config;
4562
+ }
4563
+ const apiBasePath = config.serviceConfig.apiBasePath;
4564
+ if (apiBasePath) {
4565
+ const injectedOptions = config.injected?.api ? {} : config.apiClientConfig ?? {};
4566
+ return {
4567
+ ...config,
4568
+ apiClientConfig: {
4569
+ ...injectedOptions,
4570
+ baseURL: apiBasePath
4571
+ // Service's apiBasePath always takes precedence
4572
+ }
4573
+ };
4574
+ }
4575
+ return config;
4576
+ }
4577
+ /**
4578
+ * Initialize service and wait for API client to be ready.
4579
+ * Call this in child service's static create() method after constructing the instance.
4580
+ *
4581
+ * @param service - The service instance to initialize
4582
+ * @returns The initialized service (same instance, for chaining)
4583
+ *
4584
+ * @example
4585
+ * ```typescript
4586
+ * static async create(config, options): Promise<MyService> {
4587
+ * const service = new MyService(config, options);
4588
+ * return this.initializeService(service);
4589
+ * }
4590
+ * ```
4591
+ */
4592
+ static async initializeService(service) {
4593
+ await service.ensureApiClientInitialized();
4594
+ return service;
4595
+ }
4596
+ /**
4597
+ * Ensure service is ready for operations.
4598
+ * Checks enabled/available status AND waits for API client initialization.
4599
+ * Call this at the start of all CRUD methods.
4600
+ *
4601
+ * @throws CorePackageError if service is not enabled or available
4602
+ */
4603
+ async ensureReady() {
4604
+ this.assertReady();
4605
+ await this.ensureApiClientInitialized();
4606
+ }
4519
4607
  // ─────────────────────────────────────────────────────────────────────────
4520
4608
  // Store Management (Public API)
4521
4609
  // ─────────────────────────────────────────────────────────────────────────
@@ -4988,7 +5076,7 @@ var init_BaseFrontendDomainService = __esm({
4988
5076
  */
4989
5077
  // eslint-disable-next-line complexity
4990
5078
  async fetchAll(query, options) {
4991
- this.assertReady();
5079
+ await this.ensureReady();
4992
5080
  const startTime = Date.now();
4993
5081
  if (!this.config.fetchers?.fetchAll) {
4994
5082
  throw new CorePackageError(
@@ -5073,7 +5161,7 @@ var init_BaseFrontendDomainService = __esm({
5073
5161
  */
5074
5162
  // eslint-disable-next-line complexity
5075
5163
  async fetchById(id, options) {
5076
- this.assertReady();
5164
+ await this.ensureReady();
5077
5165
  const startTime = Date.now();
5078
5166
  if (!this.config.fetchers?.fetchById) {
5079
5167
  throw new CorePackageError(
@@ -5134,7 +5222,7 @@ var init_BaseFrontendDomainService = __esm({
5134
5222
  */
5135
5223
  // eslint-disable-next-line complexity, max-lines-per-function
5136
5224
  async create(data, options) {
5137
- this.assertReady();
5225
+ await this.ensureReady();
5138
5226
  const startTime = Date.now();
5139
5227
  if (!this.config.fetchers?.create) {
5140
5228
  throw new CorePackageError(
@@ -5227,7 +5315,7 @@ var init_BaseFrontendDomainService = __esm({
5227
5315
  */
5228
5316
  // eslint-disable-next-line complexity, max-lines-per-function
5229
5317
  async update(id, data, options) {
5230
- this.assertReady();
5318
+ await this.ensureReady();
5231
5319
  const startTime = Date.now();
5232
5320
  if (!this.config.fetchers?.update) {
5233
5321
  throw new CorePackageError(
@@ -5316,7 +5404,7 @@ var init_BaseFrontendDomainService = __esm({
5316
5404
  */
5317
5405
  // eslint-disable-next-line complexity
5318
5406
  async delete(id, options) {
5319
- this.assertReady();
5407
+ await this.ensureReady();
5320
5408
  const startTime = Date.now();
5321
5409
  if (!this.config.fetchers?.delete) {
5322
5410
  throw new CorePackageError(
@@ -7741,14 +7829,11 @@ var init_FrontendExampleDomainService = __esm({
7741
7829
  // ─────────────────────────────────────────────────────────────────────────
7742
7830
  // Constructor
7743
7831
  // ─────────────────────────────────────────────────────────────────────────
7744
- // eslint-disable-next-line complexity
7745
7832
  constructor(config = {}, options) {
7746
7833
  const apiBasePath = config.apiBasePath ?? "/api/examples";
7747
7834
  super({
7748
7835
  serviceName: "ExampleFrontendService",
7749
7836
  supportedRuntimes: ["frontend"],
7750
- // API client config - uses injected options or creates from apiBasePath
7751
- apiClientConfig: options?.apiClient?.options ?? { baseURL: apiBasePath },
7752
7837
  serviceConfig: {
7753
7838
  enabled: true,
7754
7839
  apiBasePath,
@@ -7812,10 +7897,6 @@ var init_FrontendExampleDomainService = __esm({
7812
7897
  * Required by BaseFrontendDomainService
7813
7898
  */
7814
7899
  this.eventPrefix = "example";
7815
- /**
7816
- * Primary store key - the store this service can mutate
7817
- */
7818
- this.primaryStoreKey = STORE_KEYS.EXAMPLE;
7819
7900
  /**
7820
7901
  * Read-only store keys - inherits error and featureFlags from base
7821
7902
  * No need to redeclare them - they're always included by default
@@ -7838,6 +7919,14 @@ var init_FrontendExampleDomainService = __esm({
7838
7919
  // ─────────────────────────────────────────────────────────────────────────
7839
7920
  this.serviceKey = SERVICE_KEYS.EXAMPLE_FRONTEND;
7840
7921
  }
7922
+ static {
7923
+ /**
7924
+ * Primary store key for this service.
7925
+ * Used by ServiceRegistry to auto-inject the store if not specified in config.
7926
+ * Also used by base class constructor to set instance primaryStoreKey.
7927
+ */
7928
+ this.primaryStoreKey = STORE_KEYS.EXAMPLE;
7929
+ }
7841
7930
  /**
7842
7931
  * Factory method for ServiceRegistry auto-initialization.
7843
7932
  * Creates and initializes the service instance.