@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.
@@ -2255,10 +2255,16 @@ var ServiceRegistry = class _ServiceRegistry {
2255
2255
  return initPromise;
2256
2256
  }
2257
2257
  /** Build stores for service injection */
2258
- static buildStoresForService(config) {
2258
+ // eslint-disable-next-line complexity
2259
+ static buildStoresForService(config, entry) {
2259
2260
  const allKeys = /* @__PURE__ */ new Set();
2260
2261
  if (config.store) {
2261
2262
  allKeys.add(config.store);
2263
+ } else if ("primaryStoreKey" in entry.service && typeof entry.service.primaryStoreKey === "string") {
2264
+ allKeys.add(entry.service.primaryStoreKey);
2265
+ _ServiceRegistry.logger.debug(
2266
+ `Auto-resolved store key '${entry.service.primaryStoreKey}' from service class`
2267
+ );
2262
2268
  }
2263
2269
  if (config.readStores) {
2264
2270
  config.readStores.forEach((key) => allKeys.add(key));
@@ -2296,7 +2302,7 @@ var ServiceRegistry = class _ServiceRegistry {
2296
2302
  const observability = _ServiceRegistry.buildObservabilityConfig(config, entry);
2297
2303
  const storage = await _ServiceRegistry.buildStorageConfig(config, entry);
2298
2304
  const notifications = await _ServiceRegistry.buildNotificationsConfig(config, entry);
2299
- const stores = _ServiceRegistry.buildStoresForService(config);
2305
+ const stores = _ServiceRegistry.buildStoresForService(config, entry);
2300
2306
  let observabilityInstance = observability?.instance;
2301
2307
  if (observability?.dedicated && observability.config) {
2302
2308
  observabilityInstance = await _ServiceRegistry.createDedicatedObservability(
@@ -3825,6 +3831,13 @@ var Core = class _Core {
3825
3831
  /** Create fetch flags function */
3826
3832
  static createFetchFlagsFn(config, verbose) {
3827
3833
  return async () => {
3834
+ if (config?.provider !== "api") {
3835
+ _Core.log(
3836
+ `Feature flags using ${config?.provider ?? "default"} provider (no API fetch)`,
3837
+ verbose
3838
+ );
3839
+ return config?.defaults ?? {};
3840
+ }
3828
3841
  try {
3829
3842
  const client = ApiClientService.getClient();
3830
3843
  const endpoint = config?.apiEndpoint ?? "/feature-flags";
@@ -3844,6 +3857,7 @@ var Core = class _Core {
3844
3857
  /**
3845
3858
  * Initialize feature flags slice within root store
3846
3859
  */
3860
+ // eslint-disable-next-line complexity
3847
3861
  static async initializeFeatureFlags(config, verbose) {
3848
3862
  if (config?.enabled === false) {
3849
3863
  _Core.log("Feature flags disabled by configuration", verbose);
@@ -3856,11 +3870,16 @@ var Core = class _Core {
3856
3870
  );
3857
3871
  }
3858
3872
  _Core._flagConfig = config ?? {};
3859
- _Core.log("Initializing feature flags from root store...", verbose);
3873
+ const isApiProvider = config?.provider === "api";
3874
+ _Core.log(
3875
+ `Initializing feature flags from root store (provider: ${config?.provider ?? "default"})...`,
3876
+ verbose
3877
+ );
3860
3878
  const state = _Core._rootStore.getState();
3861
3879
  await state.featureFlags.initialize({
3862
3880
  defaults: _Core._flagConfig.defaults,
3863
- polling: _Core._flagConfig.polling,
3881
+ // Only enable polling for API provider
3882
+ polling: isApiProvider ? _Core._flagConfig.polling : void 0,
3864
3883
  fetchFn: _Core.createFetchFlagsFn(_Core._flagConfig, verbose),
3865
3884
  onFlagChange: _Core._flagConfig.onFlagChange,
3866
3885
  onError: _Core._flagConfig.onError
@@ -4267,13 +4286,14 @@ var BaseDomainService = class {
4267
4286
  );
4268
4287
  }
4269
4288
  };
4270
- var BaseFrontendDomainService = class extends BaseDomainService {
4289
+ var BaseFrontendDomainService = class _BaseFrontendDomainService extends BaseDomainService {
4271
4290
  // ─────────────────────────────────────────────────────────────────────────
4272
4291
  // Constructor
4273
4292
  // ─────────────────────────────────────────────────────────────────────────
4274
4293
  // eslint-disable-next-line complexity
4275
4294
  constructor(config) {
4276
- super(config);
4295
+ const resolvedConfig = _BaseFrontendDomainService.resolveApiClientConfig(config);
4296
+ super(resolvedConfig);
4277
4297
  // ─────────────────────────────────────────────────────────────────────────
4278
4298
  // Store Properties
4279
4299
  // ─────────────────────────────────────────────────────────────────────────
@@ -4299,6 +4319,11 @@ var BaseFrontendDomainService = class extends BaseDomainService {
4299
4319
  const serviceConfig = config.serviceConfig;
4300
4320
  if (serviceConfig.store !== void 0) {
4301
4321
  this.primaryStoreKey = serviceConfig.store;
4322
+ } else {
4323
+ const staticKey = this.constructor.primaryStoreKey;
4324
+ if (staticKey) {
4325
+ this.primaryStoreKey = staticKey;
4326
+ }
4302
4327
  }
4303
4328
  if (serviceConfig.readStores !== void 0) {
4304
4329
  this.readStoreKeys = Array.from(
@@ -4317,9 +4342,12 @@ var BaseFrontendDomainService = class extends BaseDomainService {
4317
4342
  this._primaryStore = primaryStore;
4318
4343
  this.logDebug(`Connected primary store: '${this.primaryStoreKey}'`);
4319
4344
  } else {
4320
- this.logWarn(
4321
- `Primary store '${this.primaryStoreKey}' not found. Store mutations (setData/updateData/setLoading) will be disabled. Configure stores in PlyazProvider to enable store integration.`
4322
- );
4345
+ const isServer = typeof globalThis.window === "undefined";
4346
+ if (!isServer) {
4347
+ this.logWarn(
4348
+ `Primary store '${this.primaryStoreKey}' not found. Store mutations (setData/updateData/setLoading) will be disabled. Configure stores in PlyazProvider to enable store integration.`
4349
+ );
4350
+ }
4323
4351
  }
4324
4352
  }
4325
4353
  for (const key of this.readStoreKeys) {
@@ -4344,6 +4372,66 @@ var BaseFrontendDomainService = class extends BaseDomainService {
4344
4372
  static {
4345
4373
  __name(this, "BaseFrontendDomainService");
4346
4374
  }
4375
+ /**
4376
+ * Auto-resolve apiClientConfig from serviceConfig.apiBasePath if not explicitly provided.
4377
+ * This reduces boilerplate in child services - they only need to set apiBasePath in config.
4378
+ *
4379
+ * Priority:
4380
+ * 1. Explicit apiClientConfig.baseURL (full control)
4381
+ * 2. serviceConfig.apiBasePath (auto-constructed, merged with injected options)
4382
+ * 3. undefined (no API client)
4383
+ *
4384
+ * When auto-constructing, merges injected API options (headers, timeout, etc.)
4385
+ * with the service's apiBasePath as baseURL.
4386
+ */
4387
+ static resolveApiClientConfig(config) {
4388
+ if (config.apiClientConfig?.baseURL) {
4389
+ return config;
4390
+ }
4391
+ const apiBasePath = config.serviceConfig.apiBasePath;
4392
+ if (apiBasePath) {
4393
+ const injectedOptions = config.injected?.api ? {} : config.apiClientConfig ?? {};
4394
+ return {
4395
+ ...config,
4396
+ apiClientConfig: {
4397
+ ...injectedOptions,
4398
+ baseURL: apiBasePath
4399
+ // Service's apiBasePath always takes precedence
4400
+ }
4401
+ };
4402
+ }
4403
+ return config;
4404
+ }
4405
+ /**
4406
+ * Initialize service and wait for API client to be ready.
4407
+ * Call this in child service's static create() method after constructing the instance.
4408
+ *
4409
+ * @param service - The service instance to initialize
4410
+ * @returns The initialized service (same instance, for chaining)
4411
+ *
4412
+ * @example
4413
+ * ```typescript
4414
+ * static async create(config, options): Promise<MyService> {
4415
+ * const service = new MyService(config, options);
4416
+ * return this.initializeService(service);
4417
+ * }
4418
+ * ```
4419
+ */
4420
+ static async initializeService(service) {
4421
+ await service.ensureApiClientInitialized();
4422
+ return service;
4423
+ }
4424
+ /**
4425
+ * Ensure service is ready for operations.
4426
+ * Checks enabled/available status AND waits for API client initialization.
4427
+ * Call this at the start of all CRUD methods.
4428
+ *
4429
+ * @throws CorePackageError if service is not enabled or available
4430
+ */
4431
+ async ensureReady() {
4432
+ this.assertReady();
4433
+ await this.ensureApiClientInitialized();
4434
+ }
4347
4435
  // ─────────────────────────────────────────────────────────────────────────
4348
4436
  // Store Management (Public API)
4349
4437
  // ─────────────────────────────────────────────────────────────────────────
@@ -4816,7 +4904,7 @@ var BaseFrontendDomainService = class extends BaseDomainService {
4816
4904
  */
4817
4905
  // eslint-disable-next-line complexity
4818
4906
  async fetchAll(query, options) {
4819
- this.assertReady();
4907
+ await this.ensureReady();
4820
4908
  const startTime = Date.now();
4821
4909
  if (!this.config.fetchers?.fetchAll) {
4822
4910
  throw new CorePackageError(
@@ -4901,7 +4989,7 @@ var BaseFrontendDomainService = class extends BaseDomainService {
4901
4989
  */
4902
4990
  // eslint-disable-next-line complexity
4903
4991
  async fetchById(id, options) {
4904
- this.assertReady();
4992
+ await this.ensureReady();
4905
4993
  const startTime = Date.now();
4906
4994
  if (!this.config.fetchers?.fetchById) {
4907
4995
  throw new CorePackageError(
@@ -4962,7 +5050,7 @@ var BaseFrontendDomainService = class extends BaseDomainService {
4962
5050
  */
4963
5051
  // eslint-disable-next-line complexity, max-lines-per-function
4964
5052
  async create(data, options) {
4965
- this.assertReady();
5053
+ await this.ensureReady();
4966
5054
  const startTime = Date.now();
4967
5055
  if (!this.config.fetchers?.create) {
4968
5056
  throw new CorePackageError(
@@ -5055,7 +5143,7 @@ var BaseFrontendDomainService = class extends BaseDomainService {
5055
5143
  */
5056
5144
  // eslint-disable-next-line complexity, max-lines-per-function
5057
5145
  async update(id, data, options) {
5058
- this.assertReady();
5146
+ await this.ensureReady();
5059
5147
  const startTime = Date.now();
5060
5148
  if (!this.config.fetchers?.update) {
5061
5149
  throw new CorePackageError(
@@ -5144,7 +5232,7 @@ var BaseFrontendDomainService = class extends BaseDomainService {
5144
5232
  */
5145
5233
  // eslint-disable-next-line complexity
5146
5234
  async delete(id, options) {
5147
- this.assertReady();
5235
+ await this.ensureReady();
5148
5236
  const startTime = Date.now();
5149
5237
  if (!this.config.fetchers?.delete) {
5150
5238
  throw new CorePackageError(
@@ -6115,14 +6203,11 @@ var FrontendExampleDomainService = class _FrontendExampleDomainService extends B
6115
6203
  // ─────────────────────────────────────────────────────────────────────────
6116
6204
  // Constructor
6117
6205
  // ─────────────────────────────────────────────────────────────────────────
6118
- // eslint-disable-next-line complexity
6119
6206
  constructor(config = {}, options) {
6120
6207
  const apiBasePath = config.apiBasePath ?? "/api/examples";
6121
6208
  super({
6122
6209
  serviceName: "ExampleFrontendService",
6123
6210
  supportedRuntimes: ["frontend"],
6124
- // API client config - uses injected options or creates from apiBasePath
6125
- apiClientConfig: options?.apiClient?.options ?? { baseURL: apiBasePath },
6126
6211
  serviceConfig: {
6127
6212
  enabled: true,
6128
6213
  apiBasePath,
@@ -6186,10 +6271,6 @@ var FrontendExampleDomainService = class _FrontendExampleDomainService extends B
6186
6271
  * Required by BaseFrontendDomainService
6187
6272
  */
6188
6273
  this.eventPrefix = "example";
6189
- /**
6190
- * Primary store key - the store this service can mutate
6191
- */
6192
- this.primaryStoreKey = STORE_KEYS.EXAMPLE;
6193
6274
  /**
6194
6275
  * Read-only store keys - inherits error and featureFlags from base
6195
6276
  * No need to redeclare them - they're always included by default
@@ -6212,6 +6293,14 @@ var FrontendExampleDomainService = class _FrontendExampleDomainService extends B
6212
6293
  // ─────────────────────────────────────────────────────────────────────────
6213
6294
  this.serviceKey = SERVICE_KEYS.EXAMPLE_FRONTEND;
6214
6295
  }
6296
+ static {
6297
+ /**
6298
+ * Primary store key for this service.
6299
+ * Used by ServiceRegistry to auto-inject the store if not specified in config.
6300
+ * Also used by base class constructor to set instance primaryStoreKey.
6301
+ */
6302
+ this.primaryStoreKey = STORE_KEYS.EXAMPLE;
6303
+ }
6215
6304
  /**
6216
6305
  * Factory method for ServiceRegistry auto-initialization.
6217
6306
  * Creates and initializes the service instance.