@empyria/restate 0.4.20 → 0.4.22

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
@@ -125,9 +125,10 @@ Cron expressions are `croner` patterns (five fields, or six with seconds for tes
125
125
  ### Serving and registering an endpoint
126
126
 
127
127
  `setupRestate({ restateAdminURL, serviceURL: 'https://agent-service.internal:9080', services })` takes one complete URL, the
128
- address Restate reaches the endpoint at. It is registered as given and the endpoint listens on its port, so the scheme and
129
- an explicit port are required (there is no separate host or port option); the health endpoint listens on the next port
130
- unless `healthPort` is set.
128
+ address Restate reaches the endpoint at. It is registered as given and the endpoint listens on its port (80 or 443 when
129
+ the URL has none or states the scheme's default), so the scheme is required (there is no separate host or port option);
130
+ pass `port` when the endpoint listens on another port than the one in the URL (a container behind a Service or proxy). The
131
+ health endpoint listens on the port after that unless `healthPort` is set.
131
132
 
132
133
  It serves, registers the deployment, and deletes it again on SIGINT/SIGTERM. Invocations in flight are
133
134
  pinned to their deployment, so deleting it strands them: a restarted process cannot finish them and they can only be
package/lib/Admin.js CHANGED
@@ -620,9 +620,11 @@ export function defaultHealthCheck(req, res, { isHealthy, deploymentId, services
620
620
  * that was removed or renamed cannot resume.
621
621
  * @param {Object} params
622
622
  * @param {string} params.restateAdminURL
623
- * @param {string} params.serviceURL Complete URL Restate uses to reach this endpoint, scheme and port included
624
- * (e.g. `https://agent-service.internal:9080`). It is registered as given, and the endpoint listens on its port, so
625
- * the port must be explicit. Scheme and port are the caller's to state, never guessed here.
623
+ * @param {string} params.serviceURL Complete URL Restate uses to reach this endpoint (e.g.
624
+ * `https://agent-service.internal:9080`). It is registered as given, and the endpoint listens on its port: 80 or 443
625
+ * when the URL has none or states the scheme's default (listening there needs the privilege to bind it).
626
+ * @param {number} [params.port] Port the endpoint listens on. Defaults to the port of `serviceURL`; set it when they
627
+ * differ (a container port behind a Service or proxy on another port).
626
628
  * @param {number} [params.healthPort] - Defaults to `port + 1`.
627
629
  * @param {Parameters<typeof restate.createEndpointHandler>[0]['services']} [params.services]
628
630
  * @param {() => void} [params.shutdownCallbackFn]
@@ -639,6 +641,7 @@ export function defaultHealthCheck(req, res, { isHealthy, deploymentId, services
639
641
  export async function setupRestate({
640
642
  restateAdminURL,
641
643
  serviceURL: serviceURLParam,
644
+ port: portParam,
642
645
  healthPort: healthPortParam,
643
646
  services = [],
644
647
  shutdownCallbackFn,
@@ -647,7 +650,8 @@ export async function setupRestate({
647
650
  keepDeploymentOnShutdown = false,
648
651
  forceRegistration = false,
649
652
  }) {
650
- const { serviceURL, port } = parseServiceURL(serviceURLParam)
653
+ const { serviceURL, port: serviceURLPort } = parseServiceURL(serviceURLParam)
654
+ const port = portParam ?? serviceURLPort
651
655
  const healthPort = healthPortParam ?? port + 1
652
656
 
653
657
  const handler = restate.createEndpointHandler({ services })
@@ -792,10 +796,9 @@ export async function setupRestate({
792
796
 
793
797
  /**
794
798
  * Validates the URL `setupRestate` registers with Restate and returns it with the port the endpoint listens on.
795
- * @param {string} serviceURL Complete http(s) URL including an explicit port
799
+ * @param {string} serviceURL Complete http(s) URL; a port left out (or equal to the scheme's default) means 80/443
796
800
  * @returns {{serviceURL: string, port: number}} `serviceURL` unchanged
797
- * @throws {Error} If it is missing, not an absolute http(s) URL, or has no explicit port (the scheme's default would
798
- * be a guess)
801
+ * @throws {Error} If it is missing or not an absolute http(s) URL
799
802
  */
800
803
  export function parseServiceURL(serviceURL) {
801
804
  if (!serviceURL) {
@@ -814,12 +817,9 @@ export function parseServiceURL(serviceURL) {
814
817
  if (url.protocol !== 'http:' && url.protocol !== 'https:') {
815
818
  throw new Error(`serviceURL must use http or https, got '${serviceURL}'`)
816
819
  }
817
- if (!url.port) {
818
- throw new Error(
819
- `serviceURL '${serviceURL}' has no explicit port: the endpoint listens on the port in the URL`,
820
- )
821
- }
822
- return { serviceURL, port: Number(url.port) }
820
+ // `URL.port` is '' for the scheme's default port, written or not; that is the port Restate dials, so listen on it.
821
+ const port = url.port ? Number(url.port) : url.protocol === 'https:' ? 443 : 80
822
+ return { serviceURL, port }
823
823
  }
824
824
 
825
825
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@empyria/restate",
3
- "version": "0.4.20",
3
+ "version": "0.4.22",
4
4
  "description": "Restate.dev helpers for the Empyria nanoservice framework",
5
5
  "license": "MIT",
6
6
  "author": "Imre Fazekas <imre.fazekas@icloud.com>",
@@ -566,9 +566,11 @@ describe('parseServiceURL', () => {
566
566
  expect(() => parseServiceURL('ftp://svc:21')).toThrow(/http or https/)
567
567
  })
568
568
 
569
- test('refuses to guess the scheme default when the URL has no explicit port', () => {
570
- expect(() => parseServiceURL('https://svc.example.com')).toThrow(/no explicit port/)
571
- expect(() => parseServiceURL('http://svc:80')).toThrow(/no explicit port/)
569
+ test("uses the scheme's default port when the URL has none or states it", () => {
570
+ expect(parseServiceURL('https://svc.example.com').port).toBe(443)
571
+ expect(parseServiceURL('https://svc.example.com:443').port).toBe(443)
572
+ expect(parseServiceURL('http://svc').port).toBe(80)
573
+ expect(parseServiceURL('http://svc:80').port).toBe(80)
572
574
  })
573
575
  })
574
576