@plyaz/core 1.10.1 → 1.11.1

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.
Files changed (36) hide show
  1. package/dist/base/observability/DatadogAdapter.d.ts.map +1 -1
  2. package/dist/domain/example/FrontendExampleDomainService.d.ts.map +1 -1
  3. package/dist/domain/featureFlags/module.d.ts.map +1 -1
  4. package/dist/domain/files/BackendFilesDomainService.d.ts +10 -13
  5. package/dist/domain/files/BackendFilesDomainService.d.ts.map +1 -1
  6. package/dist/entry-backend.js +382 -200
  7. package/dist/entry-backend.js.map +1 -1
  8. package/dist/entry-backend.mjs +280 -98
  9. package/dist/entry-backend.mjs.map +1 -1
  10. package/dist/entry-frontend-browser.js +122 -35
  11. package/dist/entry-frontend-browser.js.map +1 -1
  12. package/dist/entry-frontend-browser.mjs +123 -33
  13. package/dist/entry-frontend-browser.mjs.map +1 -1
  14. package/dist/entry-frontend.js +122 -35
  15. package/dist/entry-frontend.js.map +1 -1
  16. package/dist/entry-frontend.mjs +123 -33
  17. package/dist/entry-frontend.mjs.map +1 -1
  18. package/dist/frontend/providers/PlyazProvider.d.ts +1 -3
  19. package/dist/frontend/providers/PlyazProvider.d.ts.map +1 -1
  20. package/dist/index.js +1339 -1134
  21. package/dist/index.js.map +1 -1
  22. package/dist/index.mjs +1290 -1085
  23. package/dist/index.mjs.map +1 -1
  24. package/dist/init/CoreInitializer.d.ts +31 -1
  25. package/dist/init/CoreInitializer.d.ts.map +1 -1
  26. package/dist/init/nestjs/index.js +126 -14
  27. package/dist/init/nestjs/index.js.map +1 -1
  28. package/dist/init/nestjs/index.mjs +127 -15
  29. package/dist/init/nestjs/index.mjs.map +1 -1
  30. package/dist/services/DbService.d.ts +12 -0
  31. package/dist/services/DbService.d.ts.map +1 -1
  32. package/dist/services/NotificationService.d.ts +8 -0
  33. package/dist/services/NotificationService.d.ts.map +1 -1
  34. package/dist/services/StorageService.d.ts +8 -0
  35. package/dist/services/StorageService.d.ts.map +1 -1
  36. package/package.json +3 -3
@@ -2774,6 +2774,24 @@ var Core = class _Core {
2774
2774
  */
2775
2775
  this._rootStore = null;
2776
2776
  }
2777
+ static {
2778
+ /**
2779
+ * Injected store hook for frontend (set via setRootStoreHook before initialize).
2780
+ * This is used instead of directly importing from @plyaz/store to prevent
2781
+ * duplicate store instances when bundlers create multiple module copies.
2782
+ */
2783
+ this._injectedStoreHook = null;
2784
+ }
2785
+ /**
2786
+ * Set the root store hook for frontend use.
2787
+ * Must be called before Core.initialize() when running in browser.
2788
+ * PlyazProvider calls this automatically with the store prop.
2789
+ *
2790
+ * @param store - The useRootStore hook from @plyaz/store
2791
+ */
2792
+ static setRootStoreHook(store) {
2793
+ _Core._injectedStoreHook = store;
2794
+ }
2777
2795
  /**
2778
2796
  * Setup environment and context
2779
2797
  */
@@ -3684,8 +3702,14 @@ var Core = class _Core {
3684
3702
  static async initializeRootStore(config, verbose) {
3685
3703
  const isFrontend = typeof window !== "undefined";
3686
3704
  if (isFrontend) {
3687
- _Core.log("Using frontend root store (Zustand)", verbose);
3688
- _Core._rootStore = store.useRootStore;
3705
+ if (!_Core._injectedStoreHook) {
3706
+ throw new errors.CorePackageError(
3707
+ "Root store hook not set. Call Core.setRootStoreHook(useRootStore) before Core.initialize(), or use PlyazProvider with the store prop: <PlyazProvider store={useRootStore} ...>",
3708
+ types.ERROR_CODES.CLIENT_INITIALIZATION_FAILED
3709
+ );
3710
+ }
3711
+ _Core.log("Using frontend root store (Zustand) - injected via setRootStoreHook", verbose);
3712
+ _Core._rootStore = _Core._injectedStoreHook;
3689
3713
  } else {
3690
3714
  _Core.log("Creating backend composite store (in-memory)", verbose);
3691
3715
  const ServerErrorMiddleware = getCoreDependency("ServerErrorMiddleware");
@@ -3794,26 +3818,76 @@ var Core = class _Core {
3794
3818
  errorStore,
3795
3819
  _Core.buildErrorHandlerConfig(_Core._errorConfig)
3796
3820
  );
3821
+ _Core.setupErrorEventSubscription(verbose);
3822
+ _Core.setupErrorStoreSubscription(verbose);
3823
+ _Core.log("Global error handler initialized with CoreEventManager integration", verbose);
3824
+ if (_Core._errorConfig.httpHandler !== false) {
3825
+ await _Core.createHttpErrorHandler(_Core._errorConfig, verbose);
3826
+ }
3827
+ }
3828
+ /**
3829
+ * Log serialized errors with full details.
3830
+ */
3831
+ static logErrors(errors, prefix = "ErrorStore") {
3832
+ for (const err of errors) {
3833
+ _Core.logger.error(`[${prefix}] ${err.code}: ${err.message}`, {
3834
+ id: err.id,
3835
+ code: err.code,
3836
+ message: err.message,
3837
+ category: err.category,
3838
+ source: err.source,
3839
+ status: err.status,
3840
+ isRetryable: err.isRetryable,
3841
+ context: err.context,
3842
+ timestamp: err.timestamp
3843
+ });
3844
+ }
3845
+ }
3846
+ /**
3847
+ * Setup SYSTEM.ERROR event subscription for error store updates.
3848
+ * Backend: Also logs errors with full details.
3849
+ * Frontend: Only updates store (logging handled by store subscription).
3850
+ */
3851
+ static setupErrorEventSubscription(verbose) {
3852
+ const isBackend = types.BACKEND_RUNTIMES.includes(_Core._coreServices.runtime);
3797
3853
  const errorEventCleanup = CoreEventManager.on(
3798
3854
  core.CORE_EVENTS.SYSTEM.ERROR,
3799
3855
  (event) => {
3800
3856
  if (!_Core._rootStore) return;
3801
3857
  try {
3802
3858
  const { errors } = event.data;
3803
- if (errors && errors.length > 0) {
3804
- _Core._rootStore.getState().errors.addErrors(errors);
3805
- _Core.log(`Added ${errors.length} error(s) to store`, verbose);
3806
- }
3859
+ if (!errors || errors.length === 0) return;
3860
+ _Core._rootStore.getState().errors.addErrors(errors);
3861
+ if (isBackend) _Core.logErrors(errors);
3862
+ _Core.log(`Added ${errors.length} error(s) to store`, verbose);
3807
3863
  } catch (e) {
3808
3864
  _Core.logger.error("Failed to handle error event", { error: e });
3809
3865
  }
3810
3866
  }
3811
3867
  );
3812
3868
  _Core._eventCleanupFns.push(errorEventCleanup);
3813
- _Core.log("Global error handler initialized with CoreEventManager integration", verbose);
3814
- if (_Core._errorConfig.httpHandler !== false) {
3815
- await _Core.createHttpErrorHandler(_Core._errorConfig, verbose);
3816
- }
3869
+ }
3870
+ /**
3871
+ * Setup error store subscription for frontend logging.
3872
+ * Logs new errors when they're added to the store.
3873
+ * Only active for non-backend runtimes (browser, nextjs, nuxt, edge).
3874
+ */
3875
+ static setupErrorStoreSubscription(verbose) {
3876
+ const isFrontend = !types.BACKEND_RUNTIMES.includes(_Core._coreServices.runtime);
3877
+ if (!isFrontend || !_Core._rootStore) return;
3878
+ let prevErrorCount = 0;
3879
+ const storeUnsubscribe = _Core._rootStore.subscribe((state) => {
3880
+ const currentCount = state.errors.errorCount;
3881
+ if (currentCount <= prevErrorCount) {
3882
+ prevErrorCount = currentCount;
3883
+ return;
3884
+ }
3885
+ const newErrors = state.errors.errors.slice(0, currentCount - prevErrorCount);
3886
+ _Core.logErrors(newErrors, "ErrorStore:FE");
3887
+ prevErrorCount = currentCount;
3888
+ });
3889
+ _Core._eventCleanupFns.push(storeUnsubscribe);
3890
+ _Core.log("Error store subscription initialized for frontend", verbose);
3817
3891
  }
3818
3892
  /**
3819
3893
  * Create HTTP error handler based on detected runtime.
@@ -6820,7 +6894,7 @@ var FrontendExampleDomainService = class _FrontendExampleDomainService extends B
6820
6894
  // Constructor
6821
6895
  // ─────────────────────────────────────────────────────────────────────────
6822
6896
  constructor(config = {}, options) {
6823
- const apiBasePath = config.apiBasePath || "/api/examples";
6897
+ const apiBasePath = config.apiBasePath || "";
6824
6898
  super({
6825
6899
  serviceName: "ExampleFrontendService",
6826
6900
  supportedRuntimes: ["frontend"],
@@ -6845,20 +6919,20 @@ var FrontendExampleDomainService = class _FrontendExampleDomainService extends B
6845
6919
  // Note: Use relative paths since apiClient.baseURL is already set to apiBasePath
6846
6920
  fetchers: {
6847
6921
  fetchAll: /* @__PURE__ */ __name(async (query) => {
6848
- return this.apiClient.get("", { params: query });
6922
+ return this.apiClient.get("/examples", { params: query });
6849
6923
  }, "fetchAll"),
6850
6924
  fetchById: /* @__PURE__ */ __name(async (id) => {
6851
- return this.apiClient.get(`/${id}`);
6925
+ return this.apiClient.get(`/examples/${id}`);
6852
6926
  }, "fetchById"),
6853
6927
  create: /* @__PURE__ */ __name(async (data) => {
6854
- return this.apiClient.post("", data);
6928
+ return this.apiClient.post("/examples", data);
6855
6929
  }, "create"),
6856
6930
  update: /* @__PURE__ */ __name(async (payload) => {
6857
6931
  const { id, data } = payload;
6858
- return this.apiClient.patch(`/${id}`, data);
6932
+ return this.apiClient.patch(`/examples/${id}`, data);
6859
6933
  }, "update"),
6860
6934
  delete: /* @__PURE__ */ __name(async (id) => {
6861
- return this.apiClient.delete(`/${id}`);
6935
+ return this.apiClient.delete(`/examples/${id}`);
6862
6936
  }, "delete")
6863
6937
  }
6864
6938
  // Store handlers - customize how data syncs to store
@@ -6926,7 +7000,7 @@ var FrontendExampleDomainService = class _FrontendExampleDomainService extends B
6926
7000
  // The ?? operator only falls through on null/undefined, not empty strings.
6927
7001
  // An empty string is not a valid API path, so we treat it as "not provided" and fall through to default.
6928
7002
  // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
6929
- apiBasePath: config.apiBasePath || options?.apiClient?.options?.baseURL || "/api/examples"
7003
+ apiBasePath: config.apiBasePath || options?.apiClient?.options?.baseURL || ""
6930
7004
  };
6931
7005
  const service = new _FrontendExampleDomainService(mergedConfig, options);
6932
7006
  if (mergedConfig.autoFetch) {
@@ -7087,7 +7161,10 @@ var FrontendExampleDomainService = class _FrontendExampleDomainService extends B
7087
7161
  const response = await this.apiClient.post(endpoint, data);
7088
7162
  if (!this.isResponseSuccess(response)) {
7089
7163
  const error = this.extractResponseError(response);
7090
- throw new Error(`Failed to send email: ${JSON.stringify(error)}`);
7164
+ throw new errors.CorePackageError(
7165
+ `Failed to send email: ${JSON.stringify(error)}`,
7166
+ types.ERROR_CODES.CORE_OPERATION_FAILED
7167
+ );
7091
7168
  }
7092
7169
  const result = this.unwrapResponseData(response.data);
7093
7170
  CoreEventManager.emit(`${this.eventPrefix}:email:sent`, { result });
@@ -8629,22 +8706,27 @@ async function initializeCore(config) {
8629
8706
  });
8630
8707
  }
8631
8708
  __name(initializeCore, "initializeCore");
8632
- function createStoreRegistry() {
8709
+ function createStoreRegistry(store) {
8633
8710
  return {
8634
8711
  getStore(key) {
8635
- const state = store.useRootStore.getState();
8712
+ const state = store.getState();
8636
8713
  if (!state) {
8637
8714
  logger4.warn(
8638
8715
  "Store state is undefined - store may not be hydrated yet. This can cause side effects if called during SSR or before initialization."
8639
8716
  );
8640
8717
  return void 0;
8641
8718
  }
8642
- return state[key];
8719
+ const slice = state[key];
8720
+ logger4.debug(`[StoreRegistry] getStore('${key}')`, {
8721
+ hasSlice: !!slice,
8722
+ sliceKeys: slice ? Object.keys(slice) : []
8723
+ });
8724
+ return slice;
8643
8725
  }
8644
8726
  };
8645
8727
  }
8646
8728
  __name(createStoreRegistry, "createStoreRegistry");
8647
- async function initializeServices(config) {
8729
+ async function initializeServices(config, store) {
8648
8730
  if (!config.services || config.services.length === 0) return;
8649
8731
  if (config.verbose) {
8650
8732
  globalThis.console.log("[PlyazProvider] Initializing domain services...");
@@ -8656,7 +8738,7 @@ async function initializeServices(config) {
8656
8738
  observability: config.observability,
8657
8739
  services: config.services,
8658
8740
  // Provide store registry for injecting stores into services
8659
- stores: createStoreRegistry()
8741
+ stores: createStoreRegistry(store)
8660
8742
  });
8661
8743
  if (config.verbose) {
8662
8744
  globalThis.console.log(
@@ -8693,6 +8775,7 @@ function createServicesObject(config, featureFlagStore) {
8693
8775
  __name(createServicesObject, "createServicesObject");
8694
8776
  function PlyazProvider({
8695
8777
  children,
8778
+ store,
8696
8779
  config,
8697
8780
  loading,
8698
8781
  error: errorComponent,
@@ -8706,8 +8789,9 @@ function PlyazProvider({
8706
8789
  const initialize = react.useCallback(async () => {
8707
8790
  try {
8708
8791
  setError(null);
8792
+ Core.setRootStoreHook(store);
8709
8793
  await initializeCore(config);
8710
- await initializeServices(config);
8794
+ await initializeServices(config, store);
8711
8795
  await initializeFeatureFlags(featureFlagStore);
8712
8796
  setIsReady(true);
8713
8797
  onReady?.(createServicesObject(config, featureFlagStore));
@@ -8717,7 +8801,7 @@ function PlyazProvider({
8717
8801
  onError?.(initError);
8718
8802
  globalThis.console.error("[PlyazProvider] Initialization failed:", initError);
8719
8803
  }
8720
- }, [config, featureFlagStore, onReady, onError]);
8804
+ }, [config, store, featureFlagStore, onReady, onError]);
8721
8805
  const reinitialize = react.useCallback(async () => {
8722
8806
  setIsReady(false);
8723
8807
  ServiceRegistry.disposeAll();
@@ -8766,8 +8850,9 @@ __name(PlyazProvider, "PlyazProvider");
8766
8850
  function usePlyaz() {
8767
8851
  const context = react.useContext(PlyazContext);
8768
8852
  if (!context) {
8769
- throw new Error(
8770
- "usePlyaz must be used within a PlyazProvider. Wrap your app with <PlyazProvider config={...}>...</PlyazProvider>"
8853
+ throw new errors.CorePackageError(
8854
+ "usePlyaz must be used within a PlyazProvider. Wrap your app with <PlyazProvider config={...}>...</PlyazProvider>",
8855
+ types.ERROR_CODES.CORE_PROVIDER_NOT_FOUND
8771
8856
  );
8772
8857
  }
8773
8858
  return context;
@@ -8776,7 +8861,10 @@ __name(usePlyaz, "usePlyaz");
8776
8861
  function useApi() {
8777
8862
  const { api, isReady } = usePlyaz();
8778
8863
  if (!isReady || !api) {
8779
- throw new Error("API client is not ready. Make sure PlyazProvider has finished initializing.");
8864
+ throw new errors.CorePackageError(
8865
+ "API client is not ready. Make sure PlyazProvider has finished initializing.",
8866
+ types.ERROR_CODES.CORE_PROVIDER_INITIALIZATION_FAILED
8867
+ );
8780
8868
  }
8781
8869
  return api;
8782
8870
  }
@@ -8819,7 +8907,10 @@ __name(useEnvironment, "useEnvironment");
8819
8907
  function useService(key) {
8820
8908
  const { getService, isReady } = usePlyaz();
8821
8909
  if (!isReady) {
8822
- throw new Error(`PlyazProvider not ready. Cannot get service '${key}'.`);
8910
+ throw new errors.CorePackageError(
8911
+ `PlyazProvider not ready. Cannot get service '${key}'.`,
8912
+ types.ERROR_CODES.CORE_PROVIDER_INITIALIZATION_FAILED
8913
+ );
8823
8914
  }
8824
8915
  return react.useMemo(() => getService(key), [getService, key]);
8825
8916
  }
@@ -9066,7 +9157,7 @@ var FilesMapper = new FilesMapperClass();
9066
9157
  var logger5 = new logger$1.PackageLogger({ packageName: "core", service: "FrontendFilesDomainService" });
9067
9158
  var FrontendFilesDomainService = class _FrontendFilesDomainService extends BaseFrontendDomainService {
9068
9159
  constructor(config = {}, options) {
9069
- const apiBasePath = config.apiBasePath || "/api";
9160
+ const apiBasePath = config.apiBasePath || "";
9070
9161
  super({
9071
9162
  serviceName: "FrontendFilesDomainService",
9072
9163
  supportedRuntimes: ["frontend"],
@@ -9129,7 +9220,7 @@ var FrontendFilesDomainService = class _FrontendFilesDomainService extends BaseF
9129
9220
  // The ?? operator only falls through on null/undefined, not empty strings.
9130
9221
  // An empty string is not a valid API path, so we treat it as "not provided" and fall through to default.
9131
9222
  // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
9132
- apiBasePath: config.apiBasePath || options?.apiClient?.options?.baseURL || "/api"
9223
+ apiBasePath: config.apiBasePath || options?.apiClient?.options?.baseURL || ""
9133
9224
  };
9134
9225
  return new _FrontendFilesDomainService(mergedConfig, options);
9135
9226
  }
@@ -9358,10 +9449,6 @@ function createFeatureFlagStoreConfig(options) {
9358
9449
  }
9359
9450
  __name(createFeatureFlagStoreConfig, "createFeatureFlagStoreConfig");
9360
9451
 
9361
- Object.defineProperty(exports, "useRootStore", {
9362
- enumerable: true,
9363
- get: function () { return store.useRootStore; }
9364
- });
9365
9452
  exports.ApiClientService = ApiClientService;
9366
9453
  exports.ApiProvider = ApiProvider;
9367
9454
  exports.BaseDomainService = BaseDomainService;