From 95e530c38243ac27060dd1daf3e75e91b54a7b1e Mon Sep 17 00:00:00 2001 From: Noemi <45180344+unflxw@users.noreply.github.com> Date: Wed, 16 Jul 2025 11:43:18 +0200 Subject: [PATCH 1/5] Use return value from hooks The return value from decorators and overrides is ignored. Instead of the returned span, the initial span (which may have been modified in-place by the decorators or override) is used. Delete the `compose` function, which is now unused. --- packages/core/src/index.ts | 1 - .../src/utils/__tests__/functional.test.ts | 66 ------------------- packages/core/src/utils/functional.ts | 64 ------------------ .../use-returned-span-in-override.md | 8 +++ packages/javascript/src/index.ts | 37 +++++++++-- 5 files changed, 38 insertions(+), 138 deletions(-) delete mode 100644 packages/core/src/utils/__tests__/functional.test.ts delete mode 100644 packages/core/src/utils/functional.ts create mode 100644 packages/javascript/.changesets/use-returned-span-in-override.md diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 83087b4e..66e6d522 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -1,5 +1,4 @@ // Utils -export * from "./utils/functional" export * from "./utils/hashmap" export * from "./utils/error" export * from "./utils/url" diff --git a/packages/core/src/utils/__tests__/functional.test.ts b/packages/core/src/utils/__tests__/functional.test.ts deleted file mode 100644 index 5f7fb9b8..00000000 --- a/packages/core/src/utils/__tests__/functional.test.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { compose } from "../functional" - -describe("compose", () => { - it("composes from right to left", () => { - const double = (x: number) => x * 2 - const square = (x: number) => x * x - - expect(compose(square)(5)).toBe(25) - expect(compose(square, double)(5)).toBe(100) - expect(compose(double, square, double)(5)).toBe(200) - }) - - it("composes functions from right to left", () => { - const a = (next: (x: string) => string) => (x: string) => next(x + "a") - const b = (next: (x: string) => string) => (x: string) => next(x + "b") - const c = (next: (x: string) => string) => (x: string) => next(x + "c") - const final = (x: string) => x - - expect(compose(a, b, c)(final)("")).toBe("abc") - expect(compose(b, c, a)(final)("")).toBe("bca") - expect(compose(c, a, b)(final)("")).toBe("cab") - }) - - it("throws at runtime if argument is not a function", () => { - type sFunc = (x: number, y: number) => number - const square = (x: number, _: number) => x * x - const add = (x: number, y: number) => x + y - - expect(() => - compose(square, add, (false as unknown) as sFunc)(1, 2) - ).toThrow() - - expect(() => compose(square, add, undefined!)(1, 2)).toThrow() - - expect(() => - compose(square, add, (true as unknown) as sFunc)(1, 2) - ).toThrow() - - expect(() => - compose(square, add, (NaN as unknown) as sFunc)(1, 2) - ).toThrow() - - expect(() => - compose(square, add, ("42" as unknown) as sFunc)(1, 2) - ).toThrow() - }) - - it("can be seeded with multiple arguments", () => { - const square = (x: number, _: number) => x * x - const add = (x: number, y: number) => x + y - - expect(compose(square, add)(1, 2)).toBe(9) - }) - - it("returns the first given argument if given no functions", () => { - expect(compose()(1, 2)).toBe(1) - expect(compose()(3)).toBe(3) - expect(compose()(undefined)).toBe(undefined) - }) - - it("returns the first function if given only one", () => { - const fn = () => {} - - expect(compose(fn)).toBe(fn) - }) -}) diff --git a/packages/core/src/utils/functional.ts b/packages/core/src/utils/functional.ts deleted file mode 100644 index a86412de..00000000 --- a/packages/core/src/utils/functional.ts +++ /dev/null @@ -1,64 +0,0 @@ -/** - * Taken from from https://github.com/reduxjs/redux - * - * (This file used to be a TypeScript port of the `compose` function, but since - * Redux has been ported to TypeScript, it's now an exact copy) - */ - -type Func = (...a: T) => R - -/** - * Composes single-argument functions from right to left. The rightmost - * function can take multiple arguments as it provides the signature for the - * resulting composite function. - * - * @param funcs The functions to compose. - * @returns A function obtained by composing the argument functions from right - * to left. For example, `compose(f, g, h)` is identical to doing - * `(...args) => f(g(h(...args)))`. - */ -export function compose(): (a: R) => R - -export function compose(f: F): F - -/* two functions */ -export function compose( - f1: (a: A) => R, - f2: Func -): Func - -/* three functions */ -export function compose( - f1: (b: B) => R, - f2: (a: A) => B, - f3: Func -): Func - -/* four functions */ -export function compose( - f1: (c: C) => R, - f2: (b: B) => C, - f3: (a: A) => B, - f4: Func -): Func - -/* rest */ -export function compose( - f1: (a: any) => R, - ...funcs: Function[] -): (...args: any[]) => R - -export function compose(...funcs: Function[]): (...args: any[]) => R - -export function compose(...funcs: Function[]) { - if (funcs.length === 0) { - // infer the argument type so it is usable in inference down the line - return (arg: T) => arg - } - - if (funcs.length === 1) { - return funcs[0] - } - - return funcs.reduce((a, b) => (...args: any) => a(b(...args))) -} diff --git a/packages/javascript/.changesets/use-returned-span-in-override.md b/packages/javascript/.changesets/use-returned-span-in-override.md new file mode 100644 index 00000000..b6876a7a --- /dev/null +++ b/packages/javascript/.changesets/use-returned-span-in-override.md @@ -0,0 +1,8 @@ +--- +bump: patch +type: fix +--- + +Use returned span in override. Fix an issue where the span returned from an override function was not being used, instead using the original span. This led to confusing behaviour when the override created a new span instead of modifying the original one. + +To avoid breaking existing overrides that rely on modifying the original span without returning it, if the override function does not return a span, the original span will still be used. diff --git a/packages/javascript/src/index.ts b/packages/javascript/src/index.ts index 7c4f4132..1729e310 100644 --- a/packages/javascript/src/index.ts +++ b/packages/javascript/src/index.ts @@ -3,7 +3,7 @@ * @module Appsignal */ -import { compose, toHashMap } from "@appsignal/core" +import { toHashMap } from "@appsignal/core" import type { Breadcrumb, JSClient, Hook, HashMap } from "@appsignal/types" import { VERSION } from "./version" @@ -190,14 +190,25 @@ export default class Appsignal implements JSClient { // a "span" currently refers to a fixed point in time, as opposed to // a range or length in time. this may change in future! - const span = - error instanceof Span ? error : this._createSpanFromError(error) + let span = error instanceof Span ? error : this._createSpanFromError(error) // A Span can be "decorated" with metadata after it has been created, // but before it is sent to the API and before metadata provided // as arguments is added - if (this._hooks.decorators.length > 0) { - compose(...this._hooks.decorators)(span) + + for (const decorator of this._hooks.decorators) { + const previousSpan = span + span = decorator(span) + // In previous versions of this integration, the return value was + // ignored, and the original span was used. This was a bug, but it + // worked given an implicit expectation that the span would be + // modified in place. + // + // Avoid a breaking change for "broken" decorators that do not + // return a value by using the previous span. + if (span === undefined) { + span = previousSpan + } } if (tagsOrFn) { @@ -224,8 +235,20 @@ export default class Appsignal implements JSClient { // A Span can be "overridden" with metadata after it has been created, // but before it is sent to the API and after metadata provided // as arguments is added - if (this._hooks.overrides.length > 0) { - compose(...this._hooks.overrides)(span) + + for (const override of this._hooks.overrides) { + const previousSpan = span + span = override(span) + // In previous versions of this integration, the return value was + // ignored, and the original span was used. This was a bug, but it + // worked given an implicit expectation that the span would be + // modified in place. + // + // Avoid a breaking change for "broken" overrides that do not + // return a value by using the previous span. + if (span === undefined) { + span = previousSpan + } } span.cleanBacktracePath(this.matchBacktracePaths) From 892fff5a3d4368a1d9d81813a952de0c5e76d36a Mon Sep 17 00:00:00 2001 From: Noemi <45180344+unflxw@users.noreply.github.com> Date: Wed, 16 Jul 2025 12:45:30 +0200 Subject: [PATCH 2/5] Add span getters Add getter methods for the span's properties, so users can inspect the state of the span in overrides and make decisions based on it, without having to dig into the undocumented `._data` property. --- .../.changesets/add-getters-for-spans.md | 6 ++ .../javascript/src/__tests__/span.test.ts | 95 +++++++++++++++++++ packages/javascript/src/span.ts | 31 +++++- packages/types/src/interfaces/span.ts | 9 +- 4 files changed, 139 insertions(+), 2 deletions(-) create mode 100644 packages/javascript/.changesets/add-getters-for-spans.md diff --git a/packages/javascript/.changesets/add-getters-for-spans.md b/packages/javascript/.changesets/add-getters-for-spans.md new file mode 100644 index 00000000..eefd63f8 --- /dev/null +++ b/packages/javascript/.changesets/add-getters-for-spans.md @@ -0,0 +1,6 @@ +--- +bump: patch +type: add +--- + +Add getters for spans. Use the `getAction`, `getNamespace`, `getError`, `getTags`, `getParams`, `getBreadcrumbs`, and `getEnvironment` methods to access data about the current span. This can be used to make decisions based on the span's properties within decorators or overrides. diff --git a/packages/javascript/src/__tests__/span.test.ts b/packages/javascript/src/__tests__/span.test.ts index 23c3a416..7c61295a 100644 --- a/packages/javascript/src/__tests__/span.test.ts +++ b/packages/javascript/src/__tests__/span.test.ts @@ -230,4 +230,99 @@ describe("Span", () => { expect(span.serialize().environment).toBeUndefined() }) }) + + describe("getAction", () => { + it("returns undefined when no action is set", () => { + expect(span.getAction()).toBeUndefined() + }) + + it("returns the action when set", () => { + span.setAction("test-action") + expect(span.getAction()).toBe("test-action") + }) + }) + + describe("getNamespace", () => { + it("returns the default namespace", () => { + expect(span.getNamespace()).toBe("frontend") + }) + + it("returns the namespace when set", () => { + span.setNamespace("backend") + expect(span.getNamespace()).toBe("backend") + }) + }) + + describe("getError", () => { + it("returns the default error", () => { + const error = span.getError() + expect(error).toEqual({ + name: "NullError", + message: "No error has been set", + backtrace: [] + }) + }) + + it("returns the error when set", () => { + const testError = new Error("test error") + span.setError(testError) + const error = span.getError() + expect(error?.name).toBe("Error") + expect(error?.message).toBe("test error") + expect(error?.backtrace).toBeDefined() + }) + }) + + describe("getTags", () => { + it("returns empty object when no tags are set", () => { + expect(span.getTags()).toEqual({}) + }) + + it("returns the tags when set", () => { + span.setTags({ key: "value", another: "tag" }) + expect(span.getTags()).toEqual({ key: "value", another: "tag" }) + }) + }) + + describe("getParams", () => { + it("returns empty object when no params are set", () => { + expect(span.getParams()).toEqual({}) + }) + + it("returns the params when set", () => { + span.setParams({ key: "value", number: 42 }) + expect(span.getParams()).toEqual({ key: "value", number: 42 }) + }) + }) + + describe("getBreadcrumbs", () => { + it("returns empty array when no breadcrumbs are set", () => { + expect(span.getBreadcrumbs()).toEqual([]) + }) + + it("returns the breadcrumbs when set", () => { + const breadcrumbs = [ + { timestamp: 123456, category: "log", action: "info", message: "test" }, + { + timestamp: 123457, + category: "navigation", + action: "click", + message: "page load" + } + ] + span.setBreadcrumbs(breadcrumbs) + expect(span.getBreadcrumbs()).toEqual(breadcrumbs) + }) + }) + + describe("getEnvironment", () => { + it("returns empty object when no environment is set", () => { + expect(span.getEnvironment()).toEqual({}) + }) + + it("returns the environment when set", () => { + span.setEnvironment({ key: "value", env: "test" }) + expect(span.getEnvironment()).toEqual({ key: "value", env: "test" }) + }) + }) }) diff --git a/packages/javascript/src/span.ts b/packages/javascript/src/span.ts index 2c8427bc..1a74b573 100644 --- a/packages/javascript/src/span.ts +++ b/packages/javascript/src/span.ts @@ -8,7 +8,8 @@ import type { JSSpanData, Breadcrumb, HashMap, - HashMapValue + HashMapValue, + Error as SpanError } from "@appsignal/types" export class Span extends Serializable { @@ -34,6 +35,10 @@ export class Span extends Serializable { return this } + public getAction(): string | undefined { + return this._data.action + } + public setNamespace(name: string): this { if (!name || typeof name !== "string") { return this @@ -43,6 +48,10 @@ export class Span extends Serializable { return this } + public getNamespace(): string | undefined { + return this._data.namespace + } + public setError(error: Error | T): this { if (!error || !isError(error)) return this @@ -55,26 +64,46 @@ export class Span extends Serializable { return this } + public getError(): SpanError | undefined { + return this._data.error + } + public setTags(tags: HashMap): this { this._data.tags = { ...this._data.tags, ...toHashMapString(tags) } return this } + public getTags(): HashMap { + return this._data.tags ?? {} + } + public setParams(params: HashMap): this { this._data.params = { ...this._data.params, ...params } return this } + public getParams(): HashMap { + return this._data.params ?? {} + } + public setBreadcrumbs(breadcrumbs: Breadcrumb[]): this { this._data.breadcrumbs = breadcrumbs return this } + public getBreadcrumbs(): Breadcrumb[] { + return this._data.breadcrumbs ?? [] + } + public setEnvironment(environment: HashMap): this { this._data.environment = { ...this._data.environment, ...environment } return this } + public getEnvironment(): HashMap { + return this._data.environment ?? {} + } + // @private // Do not use this function directly. Instead, set the `matchBacktracePaths` // configuration option when initializing AppSignal. diff --git a/packages/types/src/interfaces/span.ts b/packages/types/src/interfaces/span.ts index a5443cd8..70fa38b5 100644 --- a/packages/types/src/interfaces/span.ts +++ b/packages/types/src/interfaces/span.ts @@ -1,5 +1,5 @@ import { HashMap, HashMapValue } from "../types/common" -import { Error } from "../types/error" +import { Error as SpanError } from "../types/error" import { Breadcrumb } from "./breadcrumb" /** @@ -8,18 +8,25 @@ import { Breadcrumb } from "./breadcrumb" */ export interface JSSpan { setAction(name: string): this + getAction(): string | undefined setNamespace(name: string): this + getNamespace(): string | undefined setError(error: Error | T): this + getError(): SpanError | undefined setTags(tags: HashMap): this + getTags(): HashMap setParams(params: HashMap): this + getParams(): HashMap setBreadcrumbs(breadcrumbs: Breadcrumb[]): this + getBreadcrumbs(): Breadcrumb[] setEnvironment(environment: HashMap): this + getEnvironment(): HashMap } /** From 64fde57fff2eac98ea60539b62dc2197429d1139 Mon Sep 17 00:00:00 2001 From: Noemi <45180344+unflxw@users.noreply.github.com> Date: Wed, 16 Jul 2025 12:46:57 +0200 Subject: [PATCH 3/5] Ignore errors after overrides Run the logic to ignore an error based on its message and the `ignoreErrors` configuration option after overrides have ran. This allows overrides to be used to tweak the message to trigger or skip the behaviour of this configuration option. --- ...ignore-spans-by-message-after-overrides.md | 6 ++++ packages/javascript/src/index.ts | 36 +++++-------------- 2 files changed, 14 insertions(+), 28 deletions(-) create mode 100644 packages/javascript/.changesets/ignore-spans-by-message-after-overrides.md diff --git a/packages/javascript/.changesets/ignore-spans-by-message-after-overrides.md b/packages/javascript/.changesets/ignore-spans-by-message-after-overrides.md new file mode 100644 index 00000000..df981c7b --- /dev/null +++ b/packages/javascript/.changesets/ignore-spans-by-message-after-overrides.md @@ -0,0 +1,6 @@ +--- +bump: patch +type: change +--- + +Ignore spans by message after overrides. This allows overrides to modify error messages before ignoring them, allowing the override to cause the span to be ignored, or to prevent it from being ignored. diff --git a/packages/javascript/src/index.ts b/packages/javascript/src/index.ts index 1729e310..1abed857 100644 --- a/packages/javascript/src/index.ts +++ b/packages/javascript/src/index.ts @@ -160,34 +160,6 @@ export default class Appsignal implements JSClient { error = data } - // handle user defined ignores - if (this.ignored.length !== 0) { - if (error && "message" in error) { - if ( - this.ignored.some(el => - el.test((error as { message: string }).message) - ) - ) { - console.warn(`[APPSIGNAL]: Ignored an error: ${error.message}`) - return - } - } - - if (error instanceof Span) { - const serializedError = error.serialize().error - - if ( - serializedError.message && - this.ignored.some(el => el.test(serializedError.message!)) - ) { - console.warn( - `[APPSIGNAL]: Ignored a span: ${serializedError.message}` - ) - return - } - } - } - // a "span" currently refers to a fixed point in time, as opposed to // a range or length in time. this may change in future! let span = error instanceof Span ? error : this._createSpanFromError(error) @@ -251,6 +223,14 @@ export default class Appsignal implements JSClient { } } + // Ignore user defined errors after overrides. + const message = span.getError()?.message + + if (message && this.ignored.some(el => el.test(message))) { + console.warn(`[APPSIGNAL]: Ignored a span: ${message}`) + return + } + span.cleanBacktracePath(this.matchBacktracePaths) if (Environment.supportsPromises()) { From b216d346f1bdb561b37fdbaa5eff1543f8f56a1c Mon Sep 17 00:00:00 2001 From: Noemi <45180344+unflxw@users.noreply.github.com> Date: Wed, 16 Jul 2025 13:11:07 +0200 Subject: [PATCH 4/5] Allow ignoring spans in overrides Allow for a span to be ignored by an override returning `false` from it. Along with the getters, this allows customers to implement their own span ignoring logic. --- .../allow-overrides-to-ignore-spans.md | 6 + .../javascript/src/__tests__/index.test.ts | 136 ++++++++++++++++++ packages/javascript/src/index.ts | 29 ++-- packages/types/src/index.ts | 2 +- packages/types/src/interfaces/client.ts | 6 +- packages/types/src/interfaces/hook.ts | 6 +- 6 files changed, 169 insertions(+), 16 deletions(-) create mode 100644 packages/javascript/.changesets/allow-overrides-to-ignore-spans.md diff --git a/packages/javascript/.changesets/allow-overrides-to-ignore-spans.md b/packages/javascript/.changesets/allow-overrides-to-ignore-spans.md new file mode 100644 index 00000000..8d7f0c30 --- /dev/null +++ b/packages/javascript/.changesets/allow-overrides-to-ignore-spans.md @@ -0,0 +1,6 @@ +--- +bump: patch +type: add +--- + +Allow overrides to ignore spans. Within an override function, returning `false` will cause AppSignal to ignore the span. diff --git a/packages/javascript/src/__tests__/index.test.ts b/packages/javascript/src/__tests__/index.test.ts index 449c947d..ec62eaa3 100644 --- a/packages/javascript/src/__tests__/index.test.ts +++ b/packages/javascript/src/__tests__/index.test.ts @@ -2,6 +2,7 @@ import { VERSION } from "../version" import Appsignal from "../index" import { Span } from "../span" +import { Override } from "../hook" import * as api from "../api" @@ -354,6 +355,141 @@ describe("Appsignal", () => { expect(secondSpan.serialize().action).toBe(testAction) expect(secondSpan.serialize().tags).toStrictEqual(testTag) }) + + it("ignores spans when override returns false", async () => { + const original = console.warn + console.warn = jest.fn() + + appsignal.addOverride(span => false) + + const result = await appsignal.sendError(new Error("test error")) + + expect(result).toBeUndefined() + expect(console.warn).toHaveBeenCalledWith( + "[APPSIGNAL]: Ignored a span due to override." + ) + + console.warn = original + }) + + it("can modify error message to affect ignoreErrors matching", async () => { + const ignored = [/ignore this/] + appsignal = new Appsignal({ + key: "TESTKEY", + ignoreErrors: ignored + }) + + const original = console.warn + console.warn = jest.fn() + + // First, verify the error would normally be sent + await appsignal.sendError(new Error("original error")) + expect(console.warn).not.toHaveBeenCalled() + + // Add override that modifies the error message to match ignoreErrors + appsignal.addOverride(span => { + const error = span.getError() + if (error) { + span.setError(new Error("ignore this error")) + } + return span + }) + + // Now the modified error should be ignored + const result = await appsignal.sendError(new Error("original error")) + expect(result).toBeUndefined() + expect(console.warn).toHaveBeenCalledWith( + "[APPSIGNAL]: Ignored a span: ignore this error" + ) + + console.warn = original + }) + + it("can modify error message to prevent ignoreErrors matching", async () => { + const ignored = [/ignore this/] + appsignal = new Appsignal({ + key: "TESTKEY", + ignoreErrors: ignored + }) + + const original = console.warn + console.warn = jest.fn() + + // Add override that modifies the error message to avoid ignoreErrors + appsignal.addOverride(span => { + const error = span.getError() + if (error && error.message && error.message.includes("ignore this")) { + span.setError(new Error("modified error")) + } + return span + }) + + // The error would normally be ignored, but override changes it + const result = await appsignal.sendError(new Error("ignore this error")) + expect(result).toBeDefined() + expect(console.warn).not.toHaveBeenCalledWith( + expect.stringContaining("Ignored a span:") + ) + + console.warn = original + }) + + it("uses returned span from override instead of original", async () => { + const originalAction = "original action" + const overrideAction = "override action" + const originalTags = { original: "tag" } + const overrideTags = { override: "tag" } + + // Add override that creates and returns a completely new span + appsignal.addOverride(span => { + const newSpan = new Span({ + action: overrideAction, + namespace: "test", + tags: overrideTags + }) + return newSpan + }) + + // Send error with original span properties using callback + const error = new Error("test error") + const result = await appsignal.sendError(error, span => { + span.setAction(originalAction) + span.setTags(originalTags) + }) + + // Verify the returned span has the override properties, not the original + expect(result).toBeDefined() + const returnedSpan = result as Span + expect(returnedSpan.serialize().action).toBe(overrideAction) + expect(returnedSpan.serialize().tags).toStrictEqual(overrideTags) + expect(returnedSpan.serialize().action).not.toBe(originalAction) + expect(returnedSpan.serialize().tags).not.toStrictEqual(originalTags) + }) + + it("uses original span when override returns undefined", async () => { + const originalAction = "original action" + const originalTags = { original: "tag" } + + // Add override that modifies the span but doesn't return it (returns undefined) + appsignal.addOverride((((span: Span) => { + span.setAction("modified action") + // Explicitly return undefined to test the fallback behavior + return undefined + }) as unknown) as Override) + + // Send error with original span properties + const error = new Error("test error") + const result = await appsignal.sendError(error, span => { + span.setAction(originalAction) + span.setTags(originalTags) + }) + + // Verify the returned span has the in-place modifications (even though override returned undefined) + expect(result).toBeDefined() + const returnedSpan = result as Span + expect(returnedSpan.serialize().action).toBe("modified action") + expect(returnedSpan.serialize().tags).toStrictEqual(originalTags) + }) }) describe("addBreadcrumbs", () => { diff --git a/packages/javascript/src/index.ts b/packages/javascript/src/index.ts index 1abed857..7d8f0508 100644 --- a/packages/javascript/src/index.ts +++ b/packages/javascript/src/index.ts @@ -4,7 +4,13 @@ */ import { toHashMap } from "@appsignal/core" -import type { Breadcrumb, JSClient, Hook, HashMap } from "@appsignal/types" +import type { + Breadcrumb, + JSClient, + Decorator, + Override, + HashMap +} from "@appsignal/types" import { VERSION } from "./version" import { PushApi } from "./api" @@ -26,8 +32,8 @@ export default class Appsignal implements JSClient { private _breadcrumbs: Breadcrumb[] = [] private _hooks = { - decorators: Array(), - overrides: Array() + decorators: Array(), + overrides: Array() } private _env = Environment.serialize() @@ -210,7 +216,14 @@ export default class Appsignal implements JSClient { for (const override of this._hooks.overrides) { const previousSpan = span - span = override(span) + const nextSpan = override(span) + + if (nextSpan === false) { + // If the override returns false, we ignore this span. + console.warn("[APPSIGNAL]: Ignored a span due to override.") + return + } + // In previous versions of this integration, the return value was // ignored, and the original span was used. This was a bug, but it // worked given an implicit expectation that the span would be @@ -218,9 +231,7 @@ export default class Appsignal implements JSClient { // // Avoid a breaking change for "broken" overrides that do not // return a value by using the previous span. - if (span === undefined) { - span = previousSpan - } + span = nextSpan ?? previousSpan } // Ignore user defined errors after overrides. @@ -382,7 +393,7 @@ export default class Appsignal implements JSClient { * * @return {void} */ - public addDecorator(decorator: T): void { + public addDecorator(decorator: T): void { this._hooks.decorators.push(decorator) } @@ -394,7 +405,7 @@ export default class Appsignal implements JSClient { * * @return {void} */ - public addOverride(override: T): void { + public addOverride(override: T): void { this._hooks.overrides.push(override) } diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts index f2c0c94a..0f5b3f74 100644 --- a/packages/types/src/index.ts +++ b/packages/types/src/index.ts @@ -4,4 +4,4 @@ export { Error } from "./types/error" export { JSClient } from "./interfaces/client" export { Breadcrumb } from "./interfaces/breadcrumb" export { JSSpan, JSSpanData } from "./interfaces/span" -export { Hook } from "./interfaces/hook" +export { Hook, Decorator, Override } from "./interfaces/hook" diff --git a/packages/types/src/interfaces/client.ts b/packages/types/src/interfaces/client.ts index 9e63a643..81b54fcf 100644 --- a/packages/types/src/interfaces/client.ts +++ b/packages/types/src/interfaces/client.ts @@ -1,6 +1,6 @@ import { Breadcrumb } from "./breadcrumb" import { JSSpan } from "./span" -import { Hook } from "./hook" +import { Decorator, Override } from "./hook" interface Configuration { readonly debug: boolean @@ -86,13 +86,13 @@ export interface JSClient extends BaseClient { * Registers a span decorator to be applied every time a Span * is sent to the Push API */ - addDecorator(decorator: T): void + addDecorator(decorator: T): void /** * Registers a span override to be applied every time a Span * is sent to the Push API */ - addOverride(override: T): void + addOverride(override: T): void /** * Sends a demonstration error to AppSignal. diff --git a/packages/types/src/interfaces/hook.ts b/packages/types/src/interfaces/hook.ts index f6b5c4a5..54e35db5 100644 --- a/packages/types/src/interfaces/hook.ts +++ b/packages/types/src/interfaces/hook.ts @@ -1,5 +1,5 @@ import { JSSpan } from "./span" -export interface Hook { - (span: JSSpan): JSSpan -} +export type Hook = Decorator | Override +export type Decorator = (span: JSSpan) => JSSpan +export type Override = (span: JSSpan) => JSSpan | false From f9dd80c490a8cdab1d41441ad2ce502fc35c4934 Mon Sep 17 00:00:00 2001 From: Noemi <45180344+unflxw@users.noreply.github.com> Date: Thu, 17 Jul 2025 12:34:45 +0200 Subject: [PATCH 5/5] Remove `core` and `types` packages Remove the `core` and `types` packages, folding their contents into the main `javascript` package. This causes a dependency on the `javascript` package where there previously was one on `types`, but this applies to packages that have no meaningful usage patterns independently from the `javascript` package. --- .github/workflows/ci.yml | 2 - .github/workflows/create_release_from_tag.yml | 1 - Gemfile.lock | 1 + build_matrix.yml | 8 -- package-lock.json | 67 ++--------- packages/angular/package.json | 2 +- packages/angular/src/index.ts | 8 +- packages/cli/package.json | 2 +- packages/core/.changesets/.gitkeep | 0 packages/core/.npmignore | 3 - packages/core/CHANGELOG.md | 108 ------------------ packages/core/LICENSE | 21 ---- packages/core/jest.config.js | 8 -- packages/core/package.json | 31 ----- packages/core/src/index.ts | 9 -- packages/core/src/utils/async.ts | 6 - packages/core/src/utils/environment.ts | 28 ----- packages/core/src/utils/url.ts | 12 -- packages/core/tsconfig.cjs.json | 8 -- packages/core/tsconfig.esm.json | 8 -- packages/core/tsconfig.json | 12 -- packages/ember/package.json | 2 +- packages/ember/src/index.ts | 7 +- ...l-core--and---appsignal-types--packages.md | 6 + packages/javascript/package.json | 2 - .../src}/__tests__/error.test.ts | 0 .../src}/__tests__/hashmap.test.ts | 0 .../javascript/src/__tests__/index.test.ts | 2 +- .../src/__tests__/serializable.test.ts | 0 .../src}/__tests__/url.test.ts | 2 +- packages/javascript/src/api.ts | 19 ++- .../src}/breadcrumb.ts | 2 +- packages/javascript/src/dispatcher.ts | 2 +- packages/javascript/src/environment.ts | 31 ++++- .../src/utils => javascript/src}/error.ts | 9 ++ .../src/utils => javascript/src}/hashmap.ts | 13 ++- packages/javascript/src/hook.ts | 5 + packages/javascript/src/index.ts | 20 ++-- .../src/{interfaces => }/options.ts | 0 .../{core => javascript}/src/serializable.ts | 0 packages/javascript/src/span.ts | 41 ++++--- .../src/{interfaces => }/transport.ts | 0 packages/javascript/src/transports/fetch.ts | 2 +- packages/javascript/src/transports/node.ts | 2 +- packages/javascript/src/transports/xdomain.ts | 2 +- packages/javascript/src/transports/xhr.ts | 2 +- .../plugin-breadcrumbs-console/package.json | 3 - .../src/__tests__/index.test.ts | 4 +- .../plugin-breadcrumbs-console/src/index.ts | 5 +- .../plugin-breadcrumbs-network/package.json | 2 +- .../plugin-breadcrumbs-network/src/index.ts | 4 +- packages/plugin-path-decorator/package.json | 2 +- packages/plugin-path-decorator/src/index.ts | 7 +- packages/plugin-window-events/package.json | 3 +- .../src/__tests__/index.test.ts | 4 +- packages/plugin-window-events/src/index.ts | 6 +- packages/preact/package.json | 3 +- packages/preact/src/types/component.ts | 4 +- packages/react/package.json | 3 +- .../src/__tests__/ErrorBoundary.test.tsx | 4 +- packages/react/src/types/component.ts | 7 +- packages/stimulus/package.json | 2 +- packages/stimulus/src/__tests__/index.test.ts | 4 +- packages/stimulus/src/index.ts | 7 +- packages/types/.changesets/.gitkeep | 0 packages/types/.npmignore | 3 - packages/types/CHANGELOG.md | 76 ------------ packages/types/README.md | 3 - packages/types/jest.config.js | 8 -- packages/types/package.json | 29 ----- packages/types/src/index.ts | 7 -- packages/types/src/interfaces/client.ts | 106 ----------------- packages/types/src/interfaces/hook.ts | 5 - packages/types/src/interfaces/span.ts | 45 -------- packages/types/src/types/common.ts | 17 --- packages/types/src/types/error.ts | 8 -- packages/types/tsconfig.cjs.json | 7 -- packages/types/tsconfig.esm.json | 7 -- packages/types/tsconfig.json | 12 -- packages/vue/package.json | 2 +- packages/vue/src/index.ts | 4 +- 81 files changed, 180 insertions(+), 749 deletions(-) delete mode 100644 packages/core/.changesets/.gitkeep delete mode 100644 packages/core/.npmignore delete mode 100644 packages/core/CHANGELOG.md delete mode 100644 packages/core/LICENSE delete mode 100644 packages/core/jest.config.js delete mode 100644 packages/core/package.json delete mode 100644 packages/core/src/index.ts delete mode 100644 packages/core/src/utils/async.ts delete mode 100644 packages/core/src/utils/environment.ts delete mode 100644 packages/core/src/utils/url.ts delete mode 100644 packages/core/tsconfig.cjs.json delete mode 100644 packages/core/tsconfig.esm.json delete mode 100644 packages/core/tsconfig.json create mode 100644 packages/javascript/.changesets/deprecate---appsignal-core--and---appsignal-types--packages.md rename packages/{core/src/utils => javascript/src}/__tests__/error.test.ts (100%) rename packages/{core/src/utils => javascript/src}/__tests__/hashmap.test.ts (100%) rename packages/{core => javascript}/src/__tests__/serializable.test.ts (100%) rename packages/{core/src/utils => javascript/src}/__tests__/url.test.ts (85%) rename packages/{types/src/interfaces => javascript/src}/breadcrumb.ts (86%) rename packages/{core/src/utils => javascript/src}/error.ts (88%) rename packages/{core/src/utils => javascript/src}/hashmap.ts (75%) create mode 100644 packages/javascript/src/hook.ts rename packages/javascript/src/{interfaces => }/options.ts (100%) rename packages/{core => javascript}/src/serializable.ts (100%) rename packages/javascript/src/{interfaces => }/transport.ts (100%) delete mode 100644 packages/types/.changesets/.gitkeep delete mode 100644 packages/types/.npmignore delete mode 100644 packages/types/CHANGELOG.md delete mode 100644 packages/types/README.md delete mode 100644 packages/types/jest.config.js delete mode 100644 packages/types/package.json delete mode 100644 packages/types/src/index.ts delete mode 100644 packages/types/src/interfaces/client.ts delete mode 100644 packages/types/src/interfaces/hook.ts delete mode 100644 packages/types/src/interfaces/span.ts delete mode 100644 packages/types/src/types/common.ts delete mode 100644 packages/types/src/types/error.ts delete mode 100644 packages/types/tsconfig.cjs.json delete mode 100644 packages/types/tsconfig.esm.json delete mode 100644 packages/types/tsconfig.json diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3fbd4f96..cdc503c0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -106,8 +106,6 @@ jobs: dependencies: "@angular/core@12.2.15" - package: "@appsignal/angular" dependencies: "@angular/core@11.2.14" - - package: "@appsignal/core" - dependencies: '' - package: "@appsignal/javascript" dependencies: '' - package: "@appsignal/plugin-breadcrumbs-console" diff --git a/.github/workflows/create_release_from_tag.yml b/.github/workflows/create_release_from_tag.yml index 163d3f7a..88b7bef8 100644 --- a/.github/workflows/create_release_from_tag.yml +++ b/.github/workflows/create_release_from_tag.yml @@ -4,7 +4,6 @@ on: push: tags: - "@appsignal/**" - - "!@appsignal/core@**" - "!@appsignal/cli@**" permissions: diff --git a/Gemfile.lock b/Gemfile.lock index 2916b93e..4efe2fcb 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -36,6 +36,7 @@ PLATFORMS arm64-darwin-22 arm64-darwin-24 x86_64-darwin-20 + x86_64-darwin-21 x86_64-linux DEPENDENCIES diff --git a/build_matrix.yml b/build_matrix.yml index ea225c4a..1ae79823 100644 --- a/build_matrix.yml +++ b/build_matrix.yml @@ -74,10 +74,6 @@ matrix: path: "packages/cli" variations: - name: "cli" - - package: "@appsignal/core" - path: "packages/core" - variations: - - name: "core" - package: "@appsignal/ember" path: "packages/ember" variations: @@ -158,10 +154,6 @@ matrix: - name: "stimulus@2.0.0" packages: stimulus: "2.0.0" - - package: "@appsignal/types" - path: "packages/types" - variations: - - name: "types" - package: "@appsignal/vue" path: "packages/vue" variations: diff --git a/package-lock.json b/package-lock.json index 34486845..56bdca81 100644 --- a/package-lock.json +++ b/package-lock.json @@ -67,10 +67,6 @@ "resolved": "packages/cli", "link": true }, - "node_modules/@appsignal/core": { - "resolved": "packages/core", - "link": true - }, "node_modules/@appsignal/ember": { "resolved": "packages/ember", "link": true @@ -107,10 +103,6 @@ "resolved": "packages/stimulus", "link": true }, - "node_modules/@appsignal/types": { - "resolved": "packages/types", - "link": true - }, "node_modules/@appsignal/vue": { "resolved": "packages/vue", "link": true @@ -12076,9 +12068,7 @@ "name": "@appsignal/angular", "version": "1.0.16", "license": "MIT", - "dependencies": { - "@appsignal/types": "=3.0.1" - }, + "dependencies": {}, "peerDependencies": { "@angular/core": ">= 8.0.0" } @@ -12097,22 +12087,11 @@ "cli": "bin/run" } }, - "packages/core": { - "name": "@appsignal/core", - "version": "1.1.24", - "license": "MIT", - "dependencies": { - "@appsignal/types": "=3.0.1", - "tslib": "^2.3.0" - } - }, "packages/ember": { "name": "@appsignal/ember", "version": "1.0.16", "license": "MIT", - "dependencies": { - "@appsignal/types": "=3.0.1" - }, + "dependencies": {}, "peerDependencies": { "ember-source": ">= 3.11.1" } @@ -12122,8 +12101,6 @@ "version": "1.5.0", "license": "MIT", "dependencies": { - "@appsignal/core": "=1.1.24", - "@appsignal/types": "=3.0.1", "tslib": "^2.3.0" } }, @@ -12134,43 +12111,31 @@ "dependencies": { "@appsignal/javascript": "=1.5.0" }, - "devDependencies": { - "@appsignal/types": "=3.0.1" - } + "devDependencies": {} }, "packages/plugin-breadcrumbs-network": { "name": "@appsignal/plugin-breadcrumbs-network", "version": "1.1.22", "license": "MIT", - "dependencies": { - "@appsignal/types": "=3.0.1" - } + "dependencies": {} }, "packages/plugin-path-decorator": { "name": "@appsignal/plugin-path-decorator", "version": "1.0.16", "license": "MIT", - "dependencies": { - "@appsignal/types": "=3.0.1" - } + "dependencies": {} }, "packages/plugin-window-events": { "name": "@appsignal/plugin-window-events", "version": "1.0.24", "license": "MIT", - "dependencies": { - "@appsignal/core": "=1.1.24", - "@appsignal/types": "=3.0.1" - } + "dependencies": {} }, "packages/preact": { "name": "@appsignal/preact", "version": "1.0.25", "license": "MIT", - "dependencies": { - "@appsignal/core": "=1.1.24", - "@appsignal/types": "=3.0.1" - }, + "dependencies": {}, "peerDependencies": { "preact": "^10.0.0" } @@ -12179,10 +12144,7 @@ "name": "@appsignal/react", "version": "1.0.29", "license": "MIT", - "dependencies": { - "@appsignal/core": "=1.1.24", - "@appsignal/types": "=3.0.1" - }, + "dependencies": {}, "peerDependencies": { "react": ">= 16.8.6 < 20" } @@ -12191,9 +12153,7 @@ "name": "@appsignal/stimulus", "version": "1.0.19", "license": "MIT", - "dependencies": { - "@appsignal/types": "=3.0.1" - }, + "dependencies": {}, "peerDependencies": { "@hotwired/stimulus": "^3.0", "stimulus": "^1.1" @@ -12207,18 +12167,11 @@ } } }, - "packages/types": { - "name": "@appsignal/types", - "version": "3.0.1", - "license": "MIT" - }, "packages/vue": { "name": "@appsignal/vue", "version": "1.1.5", "license": "MIT", - "dependencies": { - "@appsignal/types": "=3.0.1" - }, + "dependencies": {}, "peerDependencies": { "vue": ">= 2.6.0" } diff --git a/packages/angular/package.json b/packages/angular/package.json index 1f1977c0..21a7039a 100644 --- a/packages/angular/package.json +++ b/packages/angular/package.json @@ -22,7 +22,7 @@ "test:watch": "jest --watch" }, "dependencies": { - "@appsignal/types": "=3.0.1" + "@appsignal/javascript": "=1.5.0" }, "peerDependencies": { "@angular/core": ">= 8.0.0" diff --git a/packages/angular/src/index.ts b/packages/angular/src/index.ts index c95fcee2..f3eb81a9 100644 --- a/packages/angular/src/index.ts +++ b/packages/angular/src/index.ts @@ -1,11 +1,11 @@ -import type { JSClient } from "@appsignal/types" +import type Appsignal from "@appsignal/javascript" import { ErrorHandler, Injectable } from "@angular/core" @Injectable() export class AppsignalErrorHandler extends ErrorHandler { - private _appsignal: JSClient + private _appsignal: Appsignal - constructor(appsignal: JSClient) { + constructor(appsignal: Appsignal) { super() this._appsignal = appsignal } @@ -21,7 +21,7 @@ export class AppsignalErrorHandler extends ErrorHandler { } } -export function createErrorHandlerFactory(appsignal: JSClient): Function { +export function createErrorHandlerFactory(appsignal: Appsignal): Function { return function errorHandlerFactory(): AppsignalErrorHandler { return new AppsignalErrorHandler(appsignal) } diff --git a/packages/cli/package.json b/packages/cli/package.json index 143c7d07..5c5059cd 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -13,7 +13,7 @@ "build:watch": "tsc -p tsconfig.json -w --preserveWatchOutput", "clean": "rimraf dist coverage", "link:npm": "npm link", - "test": "jest", + "test": "jest --passWithNoTests", "test:watch": "jest --watch" }, "publishConfig": { diff --git a/packages/core/.changesets/.gitkeep b/packages/core/.changesets/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/core/.npmignore b/packages/core/.npmignore deleted file mode 100644 index 4ba00b5b..00000000 --- a/packages/core/.npmignore +++ /dev/null @@ -1,3 +0,0 @@ -* -!/dist/**/* -*.tsbuildinfo diff --git a/packages/core/CHANGELOG.md b/packages/core/CHANGELOG.md deleted file mode 100644 index 3b305a63..00000000 --- a/packages/core/CHANGELOG.md +++ /dev/null @@ -1,108 +0,0 @@ -# AppSignal Core changelog - -## 1.1.24 - -_Published on 2024-11-12._ - -### Fixed - -- Fix an issue where objects given as tags or breadcrumb metadata would have their values modified in place. (patch [e9794db](https://github.com/appsignal/appsignal-javascript/commit/e9794dbea47f5b85779a5617ea8d0d826f3147c7)) - -## 1.1.23 - -_Published on 2024-10-01._ - -### Changed - -- The package is now useUnknownInCatchVariables compliant. - - Try catch blocks in the package now check for the caught variable to be an instance of `Error` before doing any error-specific operations with it. - - (patch [c1f68df](https://github.com/appsignal/appsignal-javascript/commit/c1f68df2eabde7a2d3d2b866a54bf6969cd713c3)) - -## 1.1.22 - -_Published on 2024-04-23._ - -### Removed - -- [6ae655a](https://github.com/appsignal/appsignal-javascript/commit/6ae655af7ae04c75ce88893f7551a9c77420402a) patch - Remove dependency on `isomorphic-unfetch`. This fixes an issue where - `isomorphic-unfetch` fails to bundle properly with `esbuild` or `webpack`. - -## 1.1.21 - -_Published on 2024-04-22._ - -### Fixed - -- [ebb2adc](https://github.com/appsignal/appsignal-javascript/commit/ebb2adc81aee26b192d4eaca89df823c190bab7e) patch - Bump dependencies to remove vulnerability warning about `node-fetch@2.6.1`. The vulnerability does not apply to AppSignal's usage of it. - -## 1.1.20 - -### Changed - -- patch - Update @appsignal/types dependency to 3.0.1. - -## 1.1.19 - -### Changed - -- [bb1e8af](https://github.com/appsignal/appsignal-javascript/commit/bb1e8aff2596b8c7b0ca4c0d71ada00a7bb0fd79) patch - Stacktrace is no longer a requirement for an object to be considered an error - -## 1.1.18 - -### Fixed - -- [750d9fa](https://github.com/appsignal/appsignal-javascript/commit/750d9fa118f8a166156fd16e1ff99bcc3d93977d) patch - Fix `isError` so that it does not throw an error when the given error is not an object. - -## 1.1.17 - -### Changed - -- [449d4d4](https://github.com/appsignal/appsignal-javascript/commit/449d4d40381e7e6c13076732a8b4e7f65f94d5db) patch - Update package metadata to be more up-to-date and to specify the package location in the mono repository. -- patch - Update @appsignal/types dependency to 3.0.0. - -## 1.1.16 - -### Changed - -- patch - Update @appsignal/types dependency to 2.1.7. - -### Fixed - -- [038d1b8](https://github.com/appsignal/appsignal-javascript/commit/038d1b8beb4042b2610ee3db1c6b3bdb3c9e881f) patch - Fix distributed sourcemaps to include the referenced source properly. - -## 1.1.15 - -### Added - -- [f46c436](https://github.com/appsignal/appsignal-javascript/commit/f46c4362efd7ca8e414c3cf56c3938ecb7a5b03e) patch - Add internal `isError` utility function to check if an object is an error. - -## 1.1.14 - -- patch - Update @appsignal/types dependency to 2.1.6. - -## 1.1.13 - -- patch - Update @appsignal/types dependency to 2.1.5. - -## 1.1.12 - -- patch - Update @appsignal/types dependency to 2.1.4. - -## 1.1.11 - -- patch - Update @appsignal/types dependency to 2.1.3. - -## 1.1.10 - -- patch - Update @appsignal/types dependency to 2.1.2. - -## 1.1.9 - -- patch - Update @appsignal/types dependency to 2.1.1. - -## 1.1.8 - -- [d0d57e3](https://github.com/appsignal/appsignal-javascript/commit/d0d57e3b6cb559939fb40d3eb83760fdbc8bbad6) patch - Update tslib dependency to 2.3.x. -- patch - Update @appsignal/types dependency to 2.1.0. diff --git a/packages/core/LICENSE b/packages/core/LICENSE deleted file mode 100644 index 62968c6d..00000000 --- a/packages/core/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2019 AppSignal - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/packages/core/jest.config.js b/packages/core/jest.config.js deleted file mode 100644 index c6644a88..00000000 --- a/packages/core/jest.config.js +++ /dev/null @@ -1,8 +0,0 @@ -module.exports = { - preset: "ts-jest", - testEnvironment: "jsdom", - roots: ["/src"], - transform: { - "^.+\\.tsx?$": "ts-jest" - } -} diff --git a/packages/core/package.json b/packages/core/package.json deleted file mode 100644 index 38c0ebf6..00000000 --- a/packages/core/package.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "name": "@appsignal/core", - "version": "1.1.24", - "main": "dist/cjs/index.js", - "module": "dist/esm/index.js", - "repository": { - "type": "git", - "url": "https://github.com/appsignal/appsignal-javascript.git", - "directory": "packages/core" - }, - "license": "MIT", - "scripts": { - "build": "npm run build:cjs && npm run build:esm", - "build:esm": "tsc -p tsconfig.esm.json", - "build:esm:watch": "tsc -p tsconfig.esm.json -w --preserveWatchOutput", - "build:cjs": "tsc -p tsconfig.cjs.json", - "build:cjs:watch": "tsc -p tsconfig.cjs.json -w --preserveWatchOutput", - "build:watch": "run-p build:cjs:watch build:esm:watch", - "clean": "rimraf dist coverage", - "link:npm": "npm link", - "test": "jest", - "test:watch": "jest --watch" - }, - "publishConfig": { - "access": "public" - }, - "dependencies": { - "@appsignal/types": "=3.0.1", - "tslib": "^2.3.0" - } -} diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts deleted file mode 100644 index 66e6d522..00000000 --- a/packages/core/src/index.ts +++ /dev/null @@ -1,9 +0,0 @@ -// Utils -export * from "./utils/hashmap" -export * from "./utils/error" -export * from "./utils/url" -export * from "./utils/async" -export * from "./utils/environment" - -// Classes -export { Serializable } from "./serializable" diff --git a/packages/core/src/utils/async.ts b/packages/core/src/utils/async.ts deleted file mode 100644 index 2730c55a..00000000 --- a/packages/core/src/utils/async.ts +++ /dev/null @@ -1,6 +0,0 @@ -/** - * Returns `true` if the function is an async function. - * - * Adapted from https://davidwalsh.name/javascript-detect-async-function - */ -export const isAsync = (fn: Function) => fn.constructor.name === "AsyncFunction" diff --git a/packages/core/src/utils/environment.ts b/packages/core/src/utils/environment.ts deleted file mode 100644 index 69e5d8ea..00000000 --- a/packages/core/src/utils/environment.ts +++ /dev/null @@ -1,28 +0,0 @@ -/** - * Checks whether we're in the Node.js or Browser environment - * - * Originally from https://github.com/getsentry/sentry-javascript/ - */ - -export function isNodeEnv(): boolean { - return ( - Object.prototype.toString.call( - typeof process !== "undefined" ? process : 0 - ) === "[object process]" - ) -} - -/** - * Safely get global scope object - * - * Originally from https://github.com/getsentry/sentry-javascript/ - */ -export function getGlobalObject(): T { - return (isNodeEnv() - ? global - : typeof window !== "undefined" - ? window - : typeof self !== "undefined" - ? self - : {}) as T -} diff --git a/packages/core/src/utils/url.ts b/packages/core/src/utils/url.ts deleted file mode 100644 index eadfdaa5..00000000 --- a/packages/core/src/utils/url.ts +++ /dev/null @@ -1,12 +0,0 @@ -/** - * Encodes given object into url-friendly format - * - * @param {object} object: [object: An object that contains serializable values] - * - * @return {string} [Encoded URI params] - */ -export function urlEncode(object: { [key: string]: any }): string { - return Object.keys(object) - .map(key => `${encodeURIComponent(key)}=${encodeURIComponent(object[key])}`) - .join("&") -} diff --git a/packages/core/tsconfig.cjs.json b/packages/core/tsconfig.cjs.json deleted file mode 100644 index 699ed1b7..00000000 --- a/packages/core/tsconfig.cjs.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "./dist/cjs", - "module": "commonjs", - "importHelpers": true - } -} diff --git a/packages/core/tsconfig.esm.json b/packages/core/tsconfig.esm.json deleted file mode 100644 index d4838a04..00000000 --- a/packages/core/tsconfig.esm.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "./dist/esm", - "module": "es6", - "importHelpers": true - } -} diff --git a/packages/core/tsconfig.json b/packages/core/tsconfig.json deleted file mode 100644 index 70d0a8f8..00000000 --- a/packages/core/tsconfig.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "extends": "../../tsconfig.json", - "include": ["src/**/*"], - "exclude": [ - "src/**/__tests__", - "src/**/__mocks__" - ], - "compilerOptions": { - "rootDir": "./src", - "target": "es5" - } -} diff --git a/packages/ember/package.json b/packages/ember/package.json index 54980a6c..e32df5b1 100644 --- a/packages/ember/package.json +++ b/packages/ember/package.json @@ -22,7 +22,7 @@ "test:watch": "jest --watch" }, "dependencies": { - "@appsignal/types": "=3.0.1" + "@appsignal/javascript": "=1.5.0" }, "peerDependencies": { "ember-source": ">= 3.11.1" diff --git a/packages/ember/src/index.ts b/packages/ember/src/index.ts index 6b5d973d..8a9914b8 100644 --- a/packages/ember/src/index.ts +++ b/packages/ember/src/index.ts @@ -1,7 +1,8 @@ -import type { JSClient, JSSpan } from "@appsignal/types" +import type Appsignal from "@appsignal/javascript" +import type { Span } from "@appsignal/javascript" export function installErrorHandler( - appsignal: JSClient, + appsignal: Appsignal, Ember = (window as any).Ember ) { const prevHandler = Ember.onerror @@ -12,7 +13,7 @@ export function installErrorHandler( } Ember.onerror = function (error: Error): void { - const span = appsignal.createSpan((span: JSSpan) => span.setError(error)) + const span = appsignal.createSpan((span: Span) => span.setError(error)) appsignal.send(span) diff --git a/packages/javascript/.changesets/deprecate---appsignal-core--and---appsignal-types--packages.md b/packages/javascript/.changesets/deprecate---appsignal-core--and---appsignal-types--packages.md new file mode 100644 index 00000000..7972ad82 --- /dev/null +++ b/packages/javascript/.changesets/deprecate---appsignal-core--and---appsignal-types--packages.md @@ -0,0 +1,6 @@ +--- +bump: minor +type: deprecate +--- + +Deprecate `@appsignal/core` and `@appsignal/types` packages. Packages depending on these packages should be updated to use `@appsignal/javascript` instead. diff --git a/packages/javascript/package.json b/packages/javascript/package.json index b1c46b48..7245a544 100644 --- a/packages/javascript/package.json +++ b/packages/javascript/package.json @@ -28,8 +28,6 @@ "access": "public" }, "dependencies": { - "@appsignal/core": "=1.1.24", - "@appsignal/types": "=3.0.1", "tslib": "^2.3.0" }, "browser": { diff --git a/packages/core/src/utils/__tests__/error.test.ts b/packages/javascript/src/__tests__/error.test.ts similarity index 100% rename from packages/core/src/utils/__tests__/error.test.ts rename to packages/javascript/src/__tests__/error.test.ts diff --git a/packages/core/src/utils/__tests__/hashmap.test.ts b/packages/javascript/src/__tests__/hashmap.test.ts similarity index 100% rename from packages/core/src/utils/__tests__/hashmap.test.ts rename to packages/javascript/src/__tests__/hashmap.test.ts diff --git a/packages/javascript/src/__tests__/index.test.ts b/packages/javascript/src/__tests__/index.test.ts index ec62eaa3..b5ca6e64 100644 --- a/packages/javascript/src/__tests__/index.test.ts +++ b/packages/javascript/src/__tests__/index.test.ts @@ -79,7 +79,7 @@ describe("Appsignal", () => { expect(console.warn).toBeCalledTimes(1) expect(console.warn).toBeCalledWith( - `[APPSIGNAL]: Ignored an error: ${name}` + `[APPSIGNAL]: Ignored a span: ${name}` ) // As the regex used has the `g` flag, it would diff --git a/packages/core/src/__tests__/serializable.test.ts b/packages/javascript/src/__tests__/serializable.test.ts similarity index 100% rename from packages/core/src/__tests__/serializable.test.ts rename to packages/javascript/src/__tests__/serializable.test.ts diff --git a/packages/core/src/utils/__tests__/url.test.ts b/packages/javascript/src/__tests__/url.test.ts similarity index 85% rename from packages/core/src/utils/__tests__/url.test.ts rename to packages/javascript/src/__tests__/url.test.ts index 47e4eae7..082ef91a 100644 --- a/packages/core/src/utils/__tests__/url.test.ts +++ b/packages/javascript/src/__tests__/url.test.ts @@ -1,4 +1,4 @@ -import { urlEncode } from "../url" +import { urlEncode } from "../api" describe("urlEncode", () => { it("encodes a url string", () => { diff --git a/packages/javascript/src/api.ts b/packages/javascript/src/api.ts index 3d0b9d08..54db9b11 100644 --- a/packages/javascript/src/api.ts +++ b/packages/javascript/src/api.ts @@ -1,5 +1,3 @@ -import { urlEncode } from "@appsignal/core" - import { Environment } from "./environment" import { Span } from "./span" @@ -8,8 +6,8 @@ import { XHRTransport } from "./transports/xhr" import { FetchTransport } from "./transports/fetch" import { NodeTransport } from "./transports/node" -import { PushApiOptions } from "./interfaces/options" -import { Transport } from "./interfaces/transport" +import { PushApiOptions } from "./options" +import { Transport } from "./transport" export class PushApi { private _uri: string @@ -87,3 +85,16 @@ export class PushApi { } } } + +/** + * Encodes given object into url-friendly format + * + * @param {object} object: [object: An object that contains serializable values] + * + * @return {string} [Encoded URI params] + */ +export function urlEncode(object: { [key: string]: any }): string { + return Object.keys(object) + .map(key => `${encodeURIComponent(key)}=${encodeURIComponent(object[key])}`) + .join("&") +} diff --git a/packages/types/src/interfaces/breadcrumb.ts b/packages/javascript/src/breadcrumb.ts similarity index 86% rename from packages/types/src/interfaces/breadcrumb.ts rename to packages/javascript/src/breadcrumb.ts index c33ebcfa..4378078d 100644 --- a/packages/types/src/interfaces/breadcrumb.ts +++ b/packages/javascript/src/breadcrumb.ts @@ -1,4 +1,4 @@ -import { HashMap, HashMapValue } from "../types/common" +import { HashMap, HashMapValue } from "./hashmap" /** * Breadcrumbs are a time-ordered list of events in your application, that is diff --git a/packages/javascript/src/dispatcher.ts b/packages/javascript/src/dispatcher.ts index 98a266d7..df76f0bc 100644 --- a/packages/javascript/src/dispatcher.ts +++ b/packages/javascript/src/dispatcher.ts @@ -1,4 +1,4 @@ -import { getGlobalObject } from "@appsignal/core" +import { getGlobalObject } from "./environment" import { Queue } from "./queue" import { PushApi } from "./api" diff --git a/packages/javascript/src/environment.ts b/packages/javascript/src/environment.ts index 9047d007..b219df39 100644 --- a/packages/javascript/src/environment.ts +++ b/packages/javascript/src/environment.ts @@ -1,5 +1,3 @@ -import { getGlobalObject, isNodeEnv } from "@appsignal/core" - export class Environment { /** * Serializes the current browser environment into an object. @@ -87,3 +85,32 @@ export class Environment { ) } } + +/** + * Checks whether we're in the Node.js or Browser environment + * + * Originally from https://github.com/getsentry/sentry-javascript/ + */ + +export function isNodeEnv(): boolean { + return ( + Object.prototype.toString.call( + typeof process !== "undefined" ? process : 0 + ) === "[object process]" + ) +} + +/** + * Safely get global scope object + * + * Originally from https://github.com/getsentry/sentry-javascript/ + */ +export function getGlobalObject(): T { + return (isNodeEnv() + ? global + : typeof window !== "undefined" + ? window + : typeof self !== "undefined" + ? self + : {}) as T +} diff --git a/packages/core/src/utils/error.ts b/packages/javascript/src/error.ts similarity index 88% rename from packages/core/src/utils/error.ts rename to packages/javascript/src/error.ts index 02685ae7..41e1c055 100644 --- a/packages/core/src/utils/error.ts +++ b/packages/javascript/src/error.ts @@ -1,3 +1,12 @@ +/** + * The standard format for an error that is passed to AppSignal. + */ +export type SpanError = { + name: string + message?: string + backtrace?: string[] +} + /** * Check if the given object is an error-like object. * diff --git a/packages/core/src/utils/hashmap.ts b/packages/javascript/src/hashmap.ts similarity index 75% rename from packages/core/src/utils/hashmap.ts rename to packages/javascript/src/hashmap.ts index fb9f3485..9a09c6fb 100644 --- a/packages/core/src/utils/hashmap.ts +++ b/packages/javascript/src/hashmap.ts @@ -1,4 +1,15 @@ -import type { HashMap, HashMapValue } from "@appsignal/types" +/** + * `HashMapValue` is a union type that corresponds to the valid types accepted + * inside the AppSignal processors `HashMap` type in Rust. + */ +export type HashMapValue = string | number | boolean + +/** + * A generic HashMap, with a string as the indexable value. + */ +export type HashMap = { + [key: string]: T +} /** * Converts all values in a flat object to a string. diff --git a/packages/javascript/src/hook.ts b/packages/javascript/src/hook.ts new file mode 100644 index 00000000..3e960388 --- /dev/null +++ b/packages/javascript/src/hook.ts @@ -0,0 +1,5 @@ +import { Span } from "./span" + +export type Hook = Decorator | Override +export type Decorator = (span: Span) => Span +export type Override = (span: Span) => Span | false diff --git a/packages/javascript/src/index.ts b/packages/javascript/src/index.ts index 7d8f0508..f2d02acb 100644 --- a/packages/javascript/src/index.ts +++ b/packages/javascript/src/index.ts @@ -3,25 +3,25 @@ * @module Appsignal */ -import { toHashMap } from "@appsignal/core" -import type { - Breadcrumb, - JSClient, - Decorator, - Override, - HashMap -} from "@appsignal/types" +import type { Breadcrumb } from "./breadcrumb" +export type { Breadcrumb } +import type { Decorator, Override } from "./hook" +import type { HashMap } from "./hashmap" +export { isError } from "./error" + +import { toHashMap } from "./hashmap" import { VERSION } from "./version" import { PushApi } from "./api" import { Environment } from "./environment" import { Span } from "./span" +export { Span } import { Queue } from "./queue" import { Dispatcher } from "./dispatcher" -import { AppsignalOptions } from "./interfaces/options" +import { AppsignalOptions } from "./options" -export default class Appsignal implements JSClient { +export default class Appsignal { public VERSION = VERSION public ignored: RegExp[] = [] private matchBacktracePaths: RegExp[] = [] diff --git a/packages/javascript/src/interfaces/options.ts b/packages/javascript/src/options.ts similarity index 100% rename from packages/javascript/src/interfaces/options.ts rename to packages/javascript/src/options.ts diff --git a/packages/core/src/serializable.ts b/packages/javascript/src/serializable.ts similarity index 100% rename from packages/core/src/serializable.ts rename to packages/javascript/src/serializable.ts diff --git a/packages/javascript/src/span.ts b/packages/javascript/src/span.ts index 1a74b573..24798258 100644 --- a/packages/javascript/src/span.ts +++ b/packages/javascript/src/span.ts @@ -1,19 +1,28 @@ -import { - Serializable, - getStacktrace, - toHashMapString, - isError -} from "@appsignal/core" -import type { - JSSpanData, - Breadcrumb, - HashMap, - HashMapValue, - Error as SpanError -} from "@appsignal/types" - -export class Span extends Serializable { - constructor(span?: Partial) { +import { getStacktrace, isError } from "./error" +import { Serializable } from "./serializable" +import { toHashMapString } from "./hashmap" +import type { HashMap, HashMapValue } from "./hashmap" + +import type { Breadcrumb } from "./breadcrumb" +import type { SpanError } from "./error" + +/** + * The internal data structure of a `Span` inside the JavaScript integration. + */ +export interface SpanData { + timestamp: number + action?: string + namespace: string + error: SpanError + revision?: string + tags?: HashMap + params?: HashMap + environment?: HashMap + breadcrumbs?: Breadcrumb[] +} + +export class Span extends Serializable { + constructor(span?: Partial) { super({ timestamp: Math.round(new Date().getTime() / 1000), namespace: "frontend", diff --git a/packages/javascript/src/interfaces/transport.ts b/packages/javascript/src/transport.ts similarity index 100% rename from packages/javascript/src/interfaces/transport.ts rename to packages/javascript/src/transport.ts diff --git a/packages/javascript/src/transports/fetch.ts b/packages/javascript/src/transports/fetch.ts index c9624442..dad37343 100644 --- a/packages/javascript/src/transports/fetch.ts +++ b/packages/javascript/src/transports/fetch.ts @@ -1,4 +1,4 @@ -import { Transport } from "../interfaces/transport" +import { Transport } from "../transport" export class FetchTransport implements Transport { public url: string diff --git a/packages/javascript/src/transports/node.ts b/packages/javascript/src/transports/node.ts index 2631b2ee..d6bb3d6d 100644 --- a/packages/javascript/src/transports/node.ts +++ b/packages/javascript/src/transports/node.ts @@ -1,4 +1,4 @@ -import { Transport } from "../interfaces/transport" +import { Transport } from "../transport" import type https from "https" export class NodeTransport implements Transport { public url: string diff --git a/packages/javascript/src/transports/xdomain.ts b/packages/javascript/src/transports/xdomain.ts index 2fb0b18f..0d72b642 100644 --- a/packages/javascript/src/transports/xdomain.ts +++ b/packages/javascript/src/transports/xdomain.ts @@ -1,4 +1,4 @@ -import { Transport } from "../interfaces/transport" +import { Transport } from "../transport" // Fixes TypeScript complaining about this class // not existing diff --git a/packages/javascript/src/transports/xhr.ts b/packages/javascript/src/transports/xhr.ts index aa9953b3..87e0f3b3 100644 --- a/packages/javascript/src/transports/xhr.ts +++ b/packages/javascript/src/transports/xhr.ts @@ -1,4 +1,4 @@ -import { Transport } from "../interfaces/transport" +import { Transport } from "../transport" export class XHRTransport implements Transport { public url: string diff --git a/packages/plugin-breadcrumbs-console/package.json b/packages/plugin-breadcrumbs-console/package.json index be098c2b..aef036cd 100644 --- a/packages/plugin-breadcrumbs-console/package.json +++ b/packages/plugin-breadcrumbs-console/package.json @@ -26,8 +26,5 @@ }, "dependencies": { "@appsignal/javascript": "=1.5.0" - }, - "devDependencies": { - "@appsignal/types": "=3.0.1" } } diff --git a/packages/plugin-breadcrumbs-console/src/__tests__/index.test.ts b/packages/plugin-breadcrumbs-console/src/__tests__/index.test.ts index a890e76e..a2e14cd7 100644 --- a/packages/plugin-breadcrumbs-console/src/__tests__/index.test.ts +++ b/packages/plugin-breadcrumbs-console/src/__tests__/index.test.ts @@ -1,4 +1,4 @@ -import type { JSClient } from "@appsignal/types" +import type Appsignal from "@appsignal/javascript" import { plugin } from "../index" describe("BreadcrumbsConsolePlugin", () => { @@ -9,7 +9,7 @@ describe("BreadcrumbsConsolePlugin", () => { const errorMock = jest.spyOn(console, "error").mockImplementation(() => {}) const addBreadcrumb = jest.fn() - const mockAppsignal = ({ addBreadcrumb } as unknown) as JSClient + const mockAppsignal = ({ addBreadcrumb } as unknown) as Appsignal plugin({}).call(mockAppsignal) beforeEach(() => { diff --git a/packages/plugin-breadcrumbs-console/src/index.ts b/packages/plugin-breadcrumbs-console/src/index.ts index e3ab3eb8..a22bc802 100644 --- a/packages/plugin-breadcrumbs-console/src/index.ts +++ b/packages/plugin-breadcrumbs-console/src/index.ts @@ -1,4 +1,5 @@ -import type { JSClient, Breadcrumb } from "@appsignal/types" +import type Appsignal from "@appsignal/javascript" +import type { Breadcrumb } from "@appsignal/javascript" const SUPPORTED_CONSOLE_METHODS = ["log", "debug", "info", "warn", "error"] @@ -9,7 +10,7 @@ function consoleBreadcrumbsPlugin(options?: { [key: string]: any }) { typeof (console as any)[method] === "function" ) - return function (this: JSClient) { + return function (this: Appsignal) { const self = this CONSOLE_LOG_METHODS.forEach((method: string) => { diff --git a/packages/plugin-breadcrumbs-network/package.json b/packages/plugin-breadcrumbs-network/package.json index 271ae78b..cef9aa4b 100644 --- a/packages/plugin-breadcrumbs-network/package.json +++ b/packages/plugin-breadcrumbs-network/package.json @@ -22,7 +22,7 @@ "test:watch": "jest --watch" }, "dependencies": { - "@appsignal/types": "=3.0.1" + "@appsignal/javascript": "=1.5.0" }, "publishConfig": { "access": "public" diff --git a/packages/plugin-breadcrumbs-network/src/index.ts b/packages/plugin-breadcrumbs-network/src/index.ts index 9b91137e..f51377f0 100644 --- a/packages/plugin-breadcrumbs-network/src/index.ts +++ b/packages/plugin-breadcrumbs-network/src/index.ts @@ -1,4 +1,4 @@ -import type { JSClient } from "@appsignal/types" +import type Appsignal from "@appsignal/javascript" type PluginOptions = { // A boolean value representing whether the plugin should bind to `XMLHttpRequest` @@ -29,7 +29,7 @@ function networkBreadcrumbsPlugin(options?: Partial) { const isXhrEnabled = xhrEnabled ? "XMLHttpRequest" in window : false const isFetchEnabled = fetchEnabled ? "fetch" in window : false - return function (this: JSClient): void { + return function (this: Appsignal): void { const appsignal = this const xhrPatch = () => { diff --git a/packages/plugin-path-decorator/package.json b/packages/plugin-path-decorator/package.json index 74b3c7a4..392fd914 100644 --- a/packages/plugin-path-decorator/package.json +++ b/packages/plugin-path-decorator/package.json @@ -22,7 +22,7 @@ "test:watch": "jest --watch" }, "dependencies": { - "@appsignal/types": "=3.0.1" + "@appsignal/javascript": "=1.5.0" }, "publishConfig": { "access": "public" diff --git a/packages/plugin-path-decorator/src/index.ts b/packages/plugin-path-decorator/src/index.ts index 8f4e95e9..7683546d 100644 --- a/packages/plugin-path-decorator/src/index.ts +++ b/packages/plugin-path-decorator/src/index.ts @@ -1,8 +1,9 @@ -import type { JSClient, JSSpan } from "@appsignal/types" +import type Appsignal from "@appsignal/javascript" +import type { Span } from "@appsignal/javascript" function pathDecoratorPlugin(options?: { [key: string]: any }) { - return function (this: JSClient) { - const decorator = (span: JSSpan) => + return function (this: Appsignal) { + const decorator = (span: Span) => span.setTags({ path: window.location.pathname }) this.addDecorator(decorator) diff --git a/packages/plugin-window-events/package.json b/packages/plugin-window-events/package.json index 94004dd8..143ad264 100644 --- a/packages/plugin-window-events/package.json +++ b/packages/plugin-window-events/package.json @@ -22,8 +22,7 @@ "test:watch": "jest --watch" }, "dependencies": { - "@appsignal/core": "=1.1.24", - "@appsignal/types": "=3.0.1" + "@appsignal/javascript": "=1.5.0" }, "publishConfig": { "access": "public" diff --git a/packages/plugin-window-events/src/__tests__/index.test.ts b/packages/plugin-window-events/src/__tests__/index.test.ts index b228c3d0..dcc90fc2 100644 --- a/packages/plugin-window-events/src/__tests__/index.test.ts +++ b/packages/plugin-window-events/src/__tests__/index.test.ts @@ -1,4 +1,4 @@ -import type { JSClient } from "@appsignal/types" +import type Appsignal from "@appsignal/javascript" import { plugin } from "../index" describe("windowEventsPlugin", () => { @@ -13,7 +13,7 @@ describe("windowEventsPlugin", () => { setError: setErrorMock })), send: jest.fn() - } as unknown) as JSClient + } as unknown) as Appsignal beforeEach(() => { jest.clearAllMocks() diff --git a/packages/plugin-window-events/src/index.ts b/packages/plugin-window-events/src/index.ts index df02ffdd..d221a139 100644 --- a/packages/plugin-window-events/src/index.ts +++ b/packages/plugin-window-events/src/index.ts @@ -1,5 +1,5 @@ -import type { JSClient } from "@appsignal/types" -import { isError } from "@appsignal/core" +import type Appsignal from "@appsignal/javascript" +import { isError } from "@appsignal/javascript" function windowEventsPlugin(options?: { [key: string]: any }) { const ctx = window as Window @@ -10,7 +10,7 @@ function windowEventsPlugin(options?: { [key: string]: any }) { ...options } - return function (this: JSClient) { + return function (this: Appsignal) { const self = this const prev = { diff --git a/packages/preact/package.json b/packages/preact/package.json index b3e5612b..8489ac17 100644 --- a/packages/preact/package.json +++ b/packages/preact/package.json @@ -22,8 +22,7 @@ "test:watch": "jest --watch" }, "dependencies": { - "@appsignal/core": "=1.1.24", - "@appsignal/types": "=3.0.1" + "@appsignal/javascript": "=1.5.0" }, "peerDependencies": { "preact": "^10.0.0" diff --git a/packages/preact/src/types/component.ts b/packages/preact/src/types/component.ts index 8c7fde76..11d0815c 100644 --- a/packages/preact/src/types/component.ts +++ b/packages/preact/src/types/component.ts @@ -1,8 +1,8 @@ import { JSX } from "preact" -import type { JSClient } from "@appsignal/types" +import type Appsignal from "@appsignal/javascript" export type Props = { - instance: JSClient + instance: Appsignal action?: string children: JSX.Element fallback?: Function diff --git a/packages/react/package.json b/packages/react/package.json index 59d91ff1..186cf64d 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -22,8 +22,7 @@ "test:watch": "jest --watch" }, "dependencies": { - "@appsignal/core": "=1.1.24", - "@appsignal/types": "=3.0.1" + "@appsignal/javascript": "=1.5.0" }, "peerDependencies": { "react": ">= 16.8.6 < 20" diff --git a/packages/react/src/__tests__/ErrorBoundary.test.tsx b/packages/react/src/__tests__/ErrorBoundary.test.tsx index 54ab4ad6..6ba1431b 100644 --- a/packages/react/src/__tests__/ErrorBoundary.test.tsx +++ b/packages/react/src/__tests__/ErrorBoundary.test.tsx @@ -1,7 +1,7 @@ import React from "react" import { render, cleanup } from "@testing-library/react" import { ErrorBoundary } from "../ErrorBoundary" -import { JSSpan } from "@appsignal/types" +import { Span } from "@appsignal/javascript" describe("", () => { let instance: any @@ -81,7 +81,7 @@ describe("", () => { }) it("uses the override callback to modify the span if provided", () => { - const override = (span: JSSpan) => { + const override = (span: Span) => { span.setTags({ foo: "overriden" }) span.setAction("overriden") return span diff --git a/packages/react/src/types/component.ts b/packages/react/src/types/component.ts index 8c402c97..b7d816a6 100644 --- a/packages/react/src/types/component.ts +++ b/packages/react/src/types/component.ts @@ -1,12 +1,13 @@ -import type { JSClient, JSSpan } from "@appsignal/types" +import type Appsignal from "@appsignal/javascript" +import type { Span } from "@appsignal/javascript" import type React from "react" export type Props = { - instance: JSClient + instance: Appsignal action?: string children: React.ReactNode fallback?: (error?: Error) => React.ReactNode - override?: (span: JSSpan, error?: Error) => JSSpan + override?: (span: Span, error?: Error) => Span tags?: { [key: string]: string } } diff --git a/packages/stimulus/package.json b/packages/stimulus/package.json index d2ff493b..a234c2fb 100644 --- a/packages/stimulus/package.json +++ b/packages/stimulus/package.json @@ -22,7 +22,7 @@ "test:watch": "jest --watch" }, "dependencies": { - "@appsignal/types": "=3.0.1" + "@appsignal/javascript": "=1.5.0" }, "peerDependencies": { "@hotwired/stimulus": "^3.0", diff --git a/packages/stimulus/src/__tests__/index.test.ts b/packages/stimulus/src/__tests__/index.test.ts index d747713b..d5b1963f 100644 --- a/packages/stimulus/src/__tests__/index.test.ts +++ b/packages/stimulus/src/__tests__/index.test.ts @@ -1,5 +1,5 @@ +import type { Span } from "@appsignal/javascript" import { installErrorHandler } from "../index" -import type { JSSpan } from "@appsignal/types" describe("Stimulus errorHandler", () => { let appsignal: any @@ -16,7 +16,7 @@ describe("Stimulus errorHandler", () => { beforeEach(() => { appsignal = { - createSpan: (fn: (span: JSSpan) => void) => { + createSpan: (fn: (span: Span) => void) => { const mock = new SpanMock() fn(mock) return mock diff --git a/packages/stimulus/src/index.ts b/packages/stimulus/src/index.ts index 7c0f610b..8160b624 100644 --- a/packages/stimulus/src/index.ts +++ b/packages/stimulus/src/index.ts @@ -1,6 +1,7 @@ -import type { JSClient, JSSpan } from "@appsignal/types" +import type Appsignal from "@appsignal/javascript" +import type { Span } from "@appsignal/javascript" -export function installErrorHandler(appsignal: JSClient, application: any) { +export function installErrorHandler(appsignal: Appsignal, application: any) { const prevHandler = application.handleError application.handleError = function ( @@ -8,7 +9,7 @@ export function installErrorHandler(appsignal: JSClient, application: any) { message: string, detail: { identifier?: string } ) { - const span = appsignal.createSpan((span: JSSpan) => + const span = appsignal.createSpan((span: Span) => span .setAction(detail?.identifier || "[unknown Stimulus controller]") .setTags({ framework: "Stimulus", message }) diff --git a/packages/types/.changesets/.gitkeep b/packages/types/.changesets/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/types/.npmignore b/packages/types/.npmignore deleted file mode 100644 index 4ba00b5b..00000000 --- a/packages/types/.npmignore +++ /dev/null @@ -1,3 +0,0 @@ -* -!/dist/**/* -*.tsbuildinfo diff --git a/packages/types/CHANGELOG.md b/packages/types/CHANGELOG.md deleted file mode 100644 index 47a248d5..00000000 --- a/packages/types/CHANGELOG.md +++ /dev/null @@ -1,76 +0,0 @@ -# AppSignal types changelog - -## 3.0.1 - -### Changed - -- [9b9eadc](https://github.com/appsignal/appsignal-javascript/commit/9b9eadcd0a8bfbfe016d46d6c62920ec0536811f) patch - Update the type definition of our `setParams` and `params` span interfaces so that nested objects and arrays can be sent inside the params object. - -## 3.0.0 - -### Changed - -- [449d4d4](https://github.com/appsignal/appsignal-javascript/commit/449d4d40381e7e6c13076732a8b4e7f65f94d5db) patch - Update package metadata to be more up-to-date and to specify the package location in the mono repository. - -### Removed - -- [21c1401](https://github.com/appsignal/appsignal-javascript/commit/21c140146e616fc6f4f0fcf7dc7e9185ab0caa02) major - Remove the Node.js types from the `@appsignal/types` package. These types are now included in the `@appsignal/nodejs` package instead. - -## 2.1.7 - -### Fixed - -- [038d1b8](https://github.com/appsignal/appsignal-javascript/commit/038d1b8beb4042b2610ee3db1c6b3bdb3c9e881f) patch - Fix distributed sourcemaps to include the referenced source properly. - -## 2.1.6 - -- [e737a7f](https://github.com/appsignal/appsignal-javascript/commit/e737a7f8ca15cbe3577a7209e641b43610f0f68b) patch - Add callback argument to the `sendError` function to allow for more customization of errors sent with `sendError` and `wrap`. The `tags` and `namespace` parameters are now deprecated for both helpers. - - ```js - // Deprecated behavior - appsignal.sendError( - new Error("sendError with tags and namespace argument"), - { tag1: "value 1", tag2: "value 2" }, - "custom_namespace" - ); - - // New behavior - appsignal.sendError( - new Error("sendError with callback argument"), - function(span) { - span.setAction("SendErrorTestAction"); - span.setNamespace("custom_namespace"); - span.setTags({ tag1: "value 1", tag2: "value 2" }); - } - ); - ``` - -## 2.1.5 - -- [2ad4ccb](https://github.com/appsignal/appsignal-javascript/commit/2ad4ccbe26aa5c820eca5f4c9c204dc71d26cc82) patch - Make sendError callback argument optional for Node.js Tracer. - -## 2.1.4 - -- [3d03c0b](https://github.com/appsignal/appsignal-javascript/commit/3d03c0b6b7490d3d574dbfdaf190045d9983bb74) patch - Add sendError helper to Tracer - - The sendError() function gives the ability to track errors without - the need of a root span present in the given context. - -## 2.1.3 - -- [8bc4082](https://github.com/appsignal/appsignal-javascript/commit/8bc408201293a6e551516caa7b20c812f94a7808) patch - Deprecate addError helper for spans - - Errors are now added through the tracer in the Node.js integration - using the `setError` function. `span.addError()` is not used anymore. - -## 2.1.2 - -- [91708f8](https://github.com/appsignal/appsignal-javascript/commit/91708f841c5c6440dbc6878c855f2e3b30e0d2bd) patch - Rename addError helper functions to setError in NodeJS - -## 2.1.1 - -- [9b7f5c3](https://github.com/appsignal/appsignal-javascript/commit/9b7f5c3aadf03937f9ea2738ccd558a3f93ae90c) patch - Tracer rootSpan does not return undefined anymore, but returns a NoopSpan instead. - -## 2.1.0 - -- [ec9e2ea](https://github.com/appsignal/appsignal-javascript/commit/ec9e2eaa1466fb4ddb92a4c0b53702435541ecb4) minor - Add root span support to tracer interface diff --git a/packages/types/README.md b/packages/types/README.md deleted file mode 100644 index 1b201fc7..00000000 --- a/packages/types/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# `@appsignal/types` - -These are types which are shared across `@appsignal` packages, but kept here to avoid circular dependencies. diff --git a/packages/types/jest.config.js b/packages/types/jest.config.js deleted file mode 100644 index c6644a88..00000000 --- a/packages/types/jest.config.js +++ /dev/null @@ -1,8 +0,0 @@ -module.exports = { - preset: "ts-jest", - testEnvironment: "jsdom", - roots: ["/src"], - transform: { - "^.+\\.tsx?$": "ts-jest" - } -} diff --git a/packages/types/package.json b/packages/types/package.json deleted file mode 100644 index 3069bf08..00000000 --- a/packages/types/package.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "name": "@appsignal/types", - "version": "3.0.1", - "main": "dist/cjs/index.js", - "module": "dist/esm/index.js", - "types": "dist/cjs/index", - "repository": { - "type": "git", - "url": "https://github.com/appsignal/appsignal-javascript.git", - "directory": "packages/types" - }, - "license": "MIT", - "scripts": { - "build": "npm run build:cjs && npm run build:esm", - "build:esm": "tsc -p tsconfig.esm.json", - "build:esm:watch": "tsc -p tsconfig.esm.json -w --preserveWatchOutput", - "build:cjs": "tsc -p tsconfig.cjs.json", - "build:cjs:watch": "tsc -p tsconfig.cjs.json -w --preserveWatchOutput", - "build:watch": "run-p build:cjs:watch build:esm:watch", - "clean": "rimraf dist coverage", - "link:npm": "npm link", - "test": "jest --passWithNoTests", - "test:watch": "jest --watch" - }, - "publishConfig": { - "access": "public" - }, - "sideEffects": false -} diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts deleted file mode 100644 index 0f5b3f74..00000000 --- a/packages/types/src/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -export { HashMap, HashMapValue, Func } from "./types/common" -export { Error } from "./types/error" - -export { JSClient } from "./interfaces/client" -export { Breadcrumb } from "./interfaces/breadcrumb" -export { JSSpan, JSSpanData } from "./interfaces/span" -export { Hook, Decorator, Override } from "./interfaces/hook" diff --git a/packages/types/src/interfaces/client.ts b/packages/types/src/interfaces/client.ts deleted file mode 100644 index 81b54fcf..00000000 --- a/packages/types/src/interfaces/client.ts +++ /dev/null @@ -1,106 +0,0 @@ -import { Breadcrumb } from "./breadcrumb" -import { JSSpan } from "./span" -import { Decorator, Override } from "./hook" - -interface Configuration { - readonly debug: boolean - readonly isValid: boolean -} - -interface BaseClient { - /** - * The current version of the integration. - */ - readonly VERSION: string -} - -/** - * AppSignal for JavaScripts main class. - */ -export interface JSClient extends BaseClient { - ignored: RegExp[] - - /** - * Records and sends a browser `Error` to AppSignal. - */ - send(error: Error, fn?: (span: JSSpan) => T): Promise | void - - /** - * Records and sends a browser `Error` to AppSignal. - */ - send(error: Error, tags?: object, namespace?: string): Promise | void - - /** - * Records and sends an Appsignal `Span` object to AppSignal. - */ - send(span: JSSpan): Promise | void - - send( - data: Error | JSSpan, - tags?: object, - namespace?: string - ): Promise | void - - sendError(error: Error): Promise | void - sendError(error: Error, fn?: (span: JSSpan) => T): Promise | void - - /** - * Records and sends a browser `Error` to AppSignal. An alias to `#send()` - * to maintain compatibility. - */ - sendError( - error: Error, - tags?: object, - namespace?: string - ): Promise | void - - /** - * Registers and installs a valid plugin. - * - * A plugin is typically a function that can be used to provide a - * reference to the `Appsignal` instance via returning a function - * that can be bound to `this`. - */ - use(plugin: Function): void - - /** - * Creates a new `Span`, augmented with the current environment. - */ - createSpan(fn?: (span: JSSpan) => void): JSSpan - - /** - * Wraps and catches errors within a given function. If the function throws an - * error, a rejected `Promise` will be returned and the error thrown will be - * logged to AppSignal. - */ - wrap(fn: () => T, callbackFn?: (span: JSSpan) => T): Promise - - /** - * Wraps and catches errors within a given function. If the function throws an - * error, a rejected `Promise` will be returned and the error thrown will be - * logged to AppSignal. - */ - wrap(fn: () => T, tags?: {}, namespace?: string): Promise - - /** - * Registers a span decorator to be applied every time a Span - * is sent to the Push API - */ - addDecorator(decorator: T): void - - /** - * Registers a span override to be applied every time a Span - * is sent to the Push API - */ - addOverride(override: T): void - - /** - * Sends a demonstration error to AppSignal. - */ - demo(): void - - /** - * Adds a breadcrumb. - */ - addBreadcrumb(breadcrumb: Omit): void -} diff --git a/packages/types/src/interfaces/hook.ts b/packages/types/src/interfaces/hook.ts deleted file mode 100644 index 54e35db5..00000000 --- a/packages/types/src/interfaces/hook.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { JSSpan } from "./span" - -export type Hook = Decorator | Override -export type Decorator = (span: JSSpan) => JSSpan -export type Override = (span: JSSpan) => JSSpan | false diff --git a/packages/types/src/interfaces/span.ts b/packages/types/src/interfaces/span.ts deleted file mode 100644 index 70fa38b5..00000000 --- a/packages/types/src/interfaces/span.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { HashMap, HashMapValue } from "../types/common" -import { Error as SpanError } from "../types/error" -import { Breadcrumb } from "./breadcrumb" - -/** - * A `Span` is the name of the object that we use to capture data about the - * performance of your application, any errors and any surrounding context. - */ -export interface JSSpan { - setAction(name: string): this - getAction(): string | undefined - - setNamespace(name: string): this - getNamespace(): string | undefined - - setError(error: Error | T): this - getError(): SpanError | undefined - - setTags(tags: HashMap): this - getTags(): HashMap - - setParams(params: HashMap): this - getParams(): HashMap - - setBreadcrumbs(breadcrumbs: Breadcrumb[]): this - getBreadcrumbs(): Breadcrumb[] - - setEnvironment(environment: HashMap): this - getEnvironment(): HashMap -} - -/** - * The internal data structure of a `Span` inside the JavaScript integration. - */ -export interface JSSpanData { - timestamp: number - action?: string - namespace: string - error: Error - revision?: string - tags?: HashMap - params?: HashMap - environment?: HashMap - breadcrumbs?: Breadcrumb[] -} diff --git a/packages/types/src/types/common.ts b/packages/types/src/types/common.ts deleted file mode 100644 index 358894a8..00000000 --- a/packages/types/src/types/common.ts +++ /dev/null @@ -1,17 +0,0 @@ -/** - * `HashMapValue` is a union type that corresponds to the valid types accepted - * inside the AppSignal processors `HashMap` type in Rust. - */ -export type HashMapValue = string | number | boolean - -/** - * A generic HashMap, with a string as the indexable value. - */ -export type HashMap = { - [key: string]: T -} - -/** - * A function with a spread of arguments, returning a generic type. - */ -export type Func = (...args: any[]) => T diff --git a/packages/types/src/types/error.ts b/packages/types/src/types/error.ts deleted file mode 100644 index 10a87049..00000000 --- a/packages/types/src/types/error.ts +++ /dev/null @@ -1,8 +0,0 @@ -/** - * The standard format for an error that is passed to AppSignal. - */ -export type Error = { - name: string - message?: string - backtrace?: string[] -} diff --git a/packages/types/tsconfig.cjs.json b/packages/types/tsconfig.cjs.json deleted file mode 100644 index ac31cb33..00000000 --- a/packages/types/tsconfig.cjs.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "./dist/cjs", - "module": "commonjs" - } -} diff --git a/packages/types/tsconfig.esm.json b/packages/types/tsconfig.esm.json deleted file mode 100644 index b3f357a2..00000000 --- a/packages/types/tsconfig.esm.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "./dist/esm", - "module": "es6" - } -} diff --git a/packages/types/tsconfig.json b/packages/types/tsconfig.json deleted file mode 100644 index 70d0a8f8..00000000 --- a/packages/types/tsconfig.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "extends": "../../tsconfig.json", - "include": ["src/**/*"], - "exclude": [ - "src/**/__tests__", - "src/**/__mocks__" - ], - "compilerOptions": { - "rootDir": "./src", - "target": "es5" - } -} diff --git a/packages/vue/package.json b/packages/vue/package.json index 95eb0616..e6f0158b 100644 --- a/packages/vue/package.json +++ b/packages/vue/package.json @@ -22,7 +22,7 @@ "test:watch": "jest --watch" }, "dependencies": { - "@appsignal/types": "=3.0.1" + "@appsignal/javascript": "=1.5.0" }, "peerDependencies": { "vue": ">= 2.6.0" diff --git a/packages/vue/src/index.ts b/packages/vue/src/index.ts index 3f9f6540..9cbc7798 100644 --- a/packages/vue/src/index.ts +++ b/packages/vue/src/index.ts @@ -1,7 +1,7 @@ import { VueApp } from "./types" -import type { JSClient } from "@appsignal/types" +import type Appsignal from "@appsignal/javascript" -export function errorHandler(appsignal: JSClient, app?: VueApp) { +export function errorHandler(appsignal: Appsignal, app?: VueApp) { const version = app?.version ?? "" return function (error: any, vm: any, info: string) {