@contember/echo 0.0.27 → 0.0.28

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. package/dist/components/Echo.d.ts +3 -0
  2. package/dist/components/atoms/Button.d.ts +7 -0
  3. package/dist/components/atoms/Shape.d.ts +8 -0
  4. package/dist/components/atoms/index.d.ts +1 -0
  5. package/dist/components/icons/CheckCircleIcon.d.ts +3 -0
  6. package/dist/components/icons/ChevronRightIcon.d.ts +3 -0
  7. package/dist/components/icons/ContemberIcon.d.ts +3 -0
  8. package/dist/components/icons/ExternalLinkIcon.d.ts +3 -0
  9. package/dist/components/icons/HighlightIcon.d.ts +3 -0
  10. package/dist/components/icons/PenIcon.d.ts +3 -0
  11. package/dist/components/icons/TrashIcon.d.ts +3 -0
  12. package/dist/components/icons/XCircleIcon.d.ts +3 -0
  13. package/dist/components/icons/XIcon.d.ts +3 -0
  14. package/dist/components/icons/index.d.ts +8 -0
  15. package/dist/components/molecules/ColorSelector.d.ts +2 -0
  16. package/dist/components/molecules/DrawingToolbar.d.ts +2 -0
  17. package/dist/components/molecules/DrawingTooltip.d.ts +2 -0
  18. package/dist/components/molecules/LauncherButton.d.ts +2 -0
  19. package/dist/components/molecules/Notification.d.ts +2 -0
  20. package/dist/components/molecules/ShapeActions.d.ts +2 -0
  21. package/dist/components/molecules/StoredFeedback.d.ts +2 -0
  22. package/dist/components/molecules/WelcomeMessage.d.ts +2 -0
  23. package/dist/components/organisms/DrawingLayer.d.ts +2 -0
  24. package/dist/components/organisms/FeedbackForm.d.ts +2 -0
  25. package/dist/config/defaultText.d.ts +2 -0
  26. package/dist/config/drawingConfig.d.ts +13 -0
  27. package/dist/contexts/EchoContext.d.ts +9 -0
  28. package/dist/contexts/index.d.ts +1 -0
  29. package/dist/echo.es.js +0 -1
  30. package/dist/echo.umd.js +0 -1
  31. package/dist/stores/drawingStore.d.ts +39 -0
  32. package/dist/stores/echoStore.d.ts +14 -0
  33. package/dist/stores/feedbackStore.d.ts +12 -0
  34. package/dist/stores/index.d.ts +4 -0
  35. package/dist/stores/widgetStore.d.ts +19 -0
  36. package/dist/types.d.ts +87 -0
  37. package/dist/utils/color.d.ts +2 -0
  38. package/dist/utils/common.d.ts +1 -0
  39. package/dist/utils/console.d.ts +4 -0
  40. package/dist/utils/debounce.d.ts +1 -0
  41. package/dist/utils/device.d.ts +1 -0
  42. package/dist/utils/events.d.ts +5 -0
  43. package/dist/utils/format.d.ts +1 -0
  44. package/dist/utils/geometry.d.ts +8 -0
  45. package/dist/utils/index.d.ts +13 -0
  46. package/dist/utils/listeners.d.ts +22 -0
  47. package/dist/utils/screenshot.d.ts +2 -0
  48. package/dist/utils/storage.d.ts +28 -0
  49. package/dist/utils/svg.d.ts +13 -0
  50. package/dist/utils/validators.d.ts +2 -0
  51. package/package.json +1 -1
  52. package/dist/echo.es.js.map +0 -1
  53. package/dist/echo.umd.js.map +0 -1
@@ -0,0 +1,3 @@
1
+ import { type Component } from 'solid-js';
2
+ import type { FullEchoConfig } from '~/types';
3
+ export declare const Echo: Component<FullEchoConfig>;
@@ -0,0 +1,7 @@
1
+ import type { Component, JSX } from 'solid-js';
2
+ type ButtonProps = JSX.ButtonHTMLAttributes<HTMLButtonElement> & {
3
+ variant?: 'primary' | 'secondary';
4
+ size?: 'xs' | 'sm' | 'md' | 'lg';
5
+ };
6
+ export declare const Button: Component<ButtonProps>;
7
+ export {};
@@ -0,0 +1,8 @@
1
+ import { Component } from 'solid-js';
2
+ import type { Shape as ShapeType } from '~/types';
3
+ type ShapeProps = ShapeType & {
4
+ selectedShapeId: string | null;
5
+ onShapeClick?: (id: string) => void;
6
+ };
7
+ export declare const Shape: Component<ShapeProps>;
8
+ export {};
@@ -0,0 +1 @@
1
+ export * from './Button';
@@ -0,0 +1,3 @@
1
+ import type { Component } from 'solid-js';
2
+ import type { IconProps } from '~/types';
3
+ export declare const CheckCircleIcon: Component<IconProps>;
@@ -0,0 +1,3 @@
1
+ import type { Component } from 'solid-js';
2
+ import type { IconProps } from '~/types';
3
+ export declare const ChevronRightIcon: Component<IconProps>;
@@ -0,0 +1,3 @@
1
+ import type { Component } from 'solid-js';
2
+ import type { IconProps } from '~/types';
3
+ export declare const ContemberIcon: Component<IconProps>;
@@ -0,0 +1,3 @@
1
+ import type { Component } from 'solid-js';
2
+ import type { IconProps } from '~/types';
3
+ export declare const ExternalLinkIcon: Component<IconProps>;
@@ -0,0 +1,3 @@
1
+ import type { Component } from 'solid-js';
2
+ import type { IconProps } from '~/types';
3
+ export declare const HighlightIcon: Component<IconProps>;
@@ -0,0 +1,3 @@
1
+ import type { Component } from 'solid-js';
2
+ import type { IconProps } from '~/types';
3
+ export declare const PenIcon: Component<IconProps>;
@@ -0,0 +1,3 @@
1
+ import type { Component } from 'solid-js';
2
+ import type { IconProps } from '~/types';
3
+ export declare const TrashIcon: Component<IconProps>;
@@ -0,0 +1,3 @@
1
+ import type { Component } from 'solid-js';
2
+ import type { IconProps } from '~/types';
3
+ export declare const XCircleIcon: Component<IconProps>;
@@ -0,0 +1,3 @@
1
+ import type { Component } from 'solid-js';
2
+ import type { IconProps } from '~/types';
3
+ export declare const XIcon: Component<IconProps>;
@@ -0,0 +1,8 @@
1
+ export * from './ChevronRightIcon';
2
+ export * from './ContemberIcon';
3
+ export * from './HighlightIcon';
4
+ export * from './PenIcon';
5
+ export * from './TrashIcon';
6
+ export * from './CheckCircleIcon';
7
+ export * from './XCircleIcon';
8
+ export * from './XIcon';
@@ -0,0 +1,2 @@
1
+ import { type Component } from 'solid-js';
2
+ export declare const ColorSelector: Component;
@@ -0,0 +1,2 @@
1
+ import { type Component } from 'solid-js';
2
+ export declare const DrawingToolbar: Component;
@@ -0,0 +1,2 @@
1
+ import { type Component } from 'solid-js';
2
+ export declare const DrawingTooltip: Component;
@@ -0,0 +1,2 @@
1
+ import type { Component } from 'solid-js';
2
+ export declare const LauncherButton: Component;
@@ -0,0 +1,2 @@
1
+ import type { Component } from 'solid-js';
2
+ export declare const Notification: Component;
@@ -0,0 +1,2 @@
1
+ import { type Component } from 'solid-js';
2
+ export declare const ShapeActions: Component;
@@ -0,0 +1,2 @@
1
+ import { type Component } from 'solid-js';
2
+ export declare const StoredFeedback: Component;
@@ -0,0 +1,2 @@
1
+ import type { Component } from 'solid-js';
2
+ export declare const WelcomeMessage: Component;
@@ -0,0 +1,2 @@
1
+ import { type Component } from 'solid-js';
2
+ export declare const DrawingLayer: Component;
@@ -0,0 +1,2 @@
1
+ import { type Component } from 'solid-js';
2
+ export declare const FeedbackForm: Component;
@@ -0,0 +1,2 @@
1
+ import type { TextConfig } from '~/types';
2
+ export declare const defaultText: TextConfig;
@@ -0,0 +1,13 @@
1
+ import type { DrawingTool } from '~/types';
2
+ type ToolConfig = {
3
+ id: DrawingTool;
4
+ label: string;
5
+ getCursor: (color: string) => string;
6
+ strokeWidth: number;
7
+ opacity: {
8
+ selected: number;
9
+ default: number;
10
+ };
11
+ };
12
+ export declare const toolConfig: Record<DrawingTool, ToolConfig>;
13
+ export {};
@@ -0,0 +1,9 @@
1
+ import { type Component, JSXElement } from 'solid-js';
2
+ import { type EchoStore } from '~/stores';
3
+ import type { FullEchoConfig } from '~/types';
4
+ type EchoProviderProps = FullEchoConfig & {
5
+ children: JSXElement;
6
+ };
7
+ export declare const EchoProvider: Component<EchoProviderProps>;
8
+ export declare const useEchoStore: () => EchoStore;
9
+ export {};
@@ -0,0 +1 @@
1
+ export * from './EchoContext';
package/dist/echo.es.js CHANGED
@@ -2050,4 +2050,3 @@ function Xn(e) {
2050
2050
  export {
2051
2051
  Xn as initEcho
2052
2052
  };
2053
- //# sourceMappingURL=echo.es.js.map
package/dist/echo.umd.js CHANGED
@@ -6,4 +6,3 @@ Location: ${n}:${r}:${a}`,timestamp:new Date().toISOString()})}))},ct=()=>{k&&(c
6
6
  --primary-text-color: ${it(e.primaryColor)};
7
7
  }
8
8
  `;n(r)}),(()=>{var r=wn();return m(r,xt,null),m(r,t,null),r})()},Sn=()=>{const e=p();return[(()=>{var t=bn();return m(t,l.createComponent(Jt,{}),null),m(t,l.createComponent(rn,{}),null),m(t,l.createComponent(tn,{}),null),l.createRenderEffect(()=>u(t,"data-hidden",e.widget.state.isOpen)),t})(),(()=>{var t=pn();return m(t,l.createComponent(vn,{}),null),m(t,l.createComponent(Wt,{}),null),m(t,l.createComponent(gn,{}),null),l.createRenderEffect(()=>u(t,"data-hidden",!e.widget.state.isOpen)),t})()]},Cn=e=>{let t;const n=p(),r=()=>{requestAnimationFrame(()=>{t&&(t.style.height="0px",t.style.height=`${document.documentElement.scrollHeight}px`,n.widget.setState({dimensions:{width:document.documentElement.clientWidth,height:document.documentElement.scrollHeight}}))})};return D({event:"resize",callback:r,onMount:r}),Ze("Escape",()=>{n.widget.setState({isOpen:!1})}),Z({target:document.documentElement,options:{childList:!0,subtree:!0,attributes:!0},callback:()=>{r()}}),(()=>{var a=yn(),o=t;return typeof o=="function"?R(o,a):t=a,m(a,()=>e.children),l.createRenderEffect(i=>{var c=n.drawing.state.isDrawing,s=`${n.widget.state.dimensions.height}px`,d=`${n.widget.state.dimensions.width}px`;return c!==i.e&&u(a,"data-drawing",i.e=c),s!==i.t&&((i.t=s)!=null?a.style.setProperty("height",s):a.style.removeProperty("height")),d!==i.a&&((i.a=d)!=null?a.style.setProperty("width",d):a.style.removeProperty("width")),i},{e:void 0,t:void 0,a:void 0}),a})()},En={welcomeMessage:{text:"Click here to leave feedback",closeAriaLabel:"Close welcome message"},feedbackForm:{title:"Send Feedback",placeholder:"What's on your mind? We'd love to hear your feedback...",screenshotAlt:"Screenshot Preview",submitButton:"Send Feedback",minimizeTitle:"Minimize",expandTitle:"Expand",closeTitle:"Close",showFormTitle:"Show Feedback Form"},notification:{successTitle:"Thank you for your feedback!",errorTitle:"Something went wrong.",errorMessage:"Failed to send feedback. Please try again.",hideTitle:"Hide notification"},drawingTooltip:{text:"Click & drag to draw"}};let q=null;function Pn(e){q&&(console.warn("Echo widget is already initialized. Cleaning up previous instance..."),q());try{mt(e),st();const{position:t="bottom-right",primaryColor:n="#6227dc",onSubmit:r,textConfig:a={}}=e,o=ye(En,a),i=document.createElement("div");i.id="echo-container",document.body.appendChild(i);const c=Be(()=>l.createComponent(xn,{position:t,primaryColor:n,textConfig:o,onSubmit:async d=>await r({...d,console:xe()})}),i),s=()=>{c(),i.remove(),ct(),q=null};return window.addEventListener("unload",s,{once:!0}),q=s,s}catch(t){throw console.error("Echo initialization failed:",t),t}}E.initEcho=Pn,Object.defineProperty(E,Symbol.toStringTag,{value:"Module"})});
9
- //# sourceMappingURL=echo.umd.js.map
@@ -0,0 +1,39 @@
1
+ import type { DrawingTool, FullEchoConfig, Point, Shape } from '~/types';
2
+ export type DrawingState = {
3
+ isDrawing: boolean;
4
+ selectedShapeId: string | null;
5
+ selectedTool: DrawingTool;
6
+ selectedColor: string;
7
+ shapes: Shape[];
8
+ currentPoints: Point[];
9
+ showTooltip: boolean;
10
+ mousePosition: Point;
11
+ hasDrawn: boolean;
12
+ isDragging: boolean;
13
+ dragStartPos: Point | null;
14
+ initialClickPos: Point | null;
15
+ dragOffset: Point | null;
16
+ cursor: string;
17
+ };
18
+ export type DrawingStore = {
19
+ state: DrawingState;
20
+ setState: (state: Partial<DrawingState>, isClearing?: boolean) => void;
21
+ methods: {
22
+ startDrawing: (initialPoint: Point) => void;
23
+ updateDrawing: (point: Point) => void;
24
+ finishDrawing: () => void;
25
+ handleShapeClick: (shapeId: string) => void;
26
+ handleStart: (e: MouseEvent | TouchEvent) => void;
27
+ handleMove: (e: MouseEvent | TouchEvent) => void;
28
+ handleEnd: (e: MouseEvent | TouchEvent) => void;
29
+ handleEnter: (e: MouseEvent | TouchEvent) => void;
30
+ handleLeave: (e: MouseEvent | TouchEvent) => void;
31
+ startDrag: (point: Point) => void;
32
+ stopDrag: () => void;
33
+ setInitialClick: (point: Point | null) => void;
34
+ updateDragOffset: (shape: {
35
+ points: Point[];
36
+ }, point: Point) => void;
37
+ };
38
+ };
39
+ export declare const createDrawingStore: (config: FullEchoConfig, currentPageKey: string, onStateChange?: (state: Partial<DrawingState>, isClearing?: boolean) => void) => DrawingStore;
@@ -0,0 +1,14 @@
1
+ import type { EchoConfig, FullEchoConfig } from '~/types';
2
+ import { type DrawingStore } from './drawingStore';
3
+ import { type FeedbackStore } from './feedbackStore';
4
+ import { type WidgetStore } from './widgetStore';
5
+ export type EchoStore = {
6
+ feedback: FeedbackStore;
7
+ drawing: DrawingStore;
8
+ widget: WidgetStore;
9
+ methods: {
10
+ reset: () => void;
11
+ submit: EchoConfig['onSubmit'];
12
+ };
13
+ };
14
+ export declare const createEchoStore: (config: FullEchoConfig) => EchoStore;
@@ -0,0 +1,12 @@
1
+ import type { FullEchoConfig, Screenshot } from '~/types';
2
+ export type FeedbackState = {
3
+ comment: string;
4
+ screenshot?: Screenshot;
5
+ isCapturing: boolean;
6
+ isMinimized: boolean;
7
+ };
8
+ export type FeedbackStore = {
9
+ state: FeedbackState;
10
+ setState: (state: Partial<FeedbackState>, isClearing?: boolean) => void;
11
+ };
12
+ export declare const createFeedbackStore: (config: FullEchoConfig, currentPageKey: string, onStateChange?: (state: Partial<FeedbackState>, isClearing?: boolean) => void) => FeedbackStore;
@@ -0,0 +1,4 @@
1
+ export * from './echoStore';
2
+ export * from './drawingStore';
3
+ export * from './feedbackStore';
4
+ export * from './widgetStore';
@@ -0,0 +1,19 @@
1
+ import type { FullEchoConfig, Notification, TextConfig } from '~/types';
2
+ export type WidgetState = {
3
+ text: TextConfig;
4
+ isOpen: boolean;
5
+ primaryColor: string;
6
+ notification: Notification;
7
+ dimensions: {
8
+ width: number;
9
+ height: number;
10
+ };
11
+ isStoredFeedbackOpen: boolean;
12
+ pagesCount: number;
13
+ welcomeMessageIsClosing: boolean;
14
+ };
15
+ export type WidgetStore = {
16
+ state: WidgetState;
17
+ setState: (state: Partial<WidgetState>) => void;
18
+ };
19
+ export declare const createWidgetStore: (config: FullEchoConfig, currentPageKey: string) => WidgetStore;
@@ -0,0 +1,87 @@
1
+ export type Screenshot = `data:image/png;base64,${string}`;
2
+ export type BrowserInfo = {
3
+ width: number;
4
+ height: number;
5
+ screenWidth: number;
6
+ screenHeight: number;
7
+ };
8
+ export type Metadata = {
9
+ url: string;
10
+ userAgent: string;
11
+ timestamp: string;
12
+ browserInfo: BrowserInfo;
13
+ };
14
+ export type ConsoleEntry = {
15
+ type: 'log' | 'warn' | 'error';
16
+ message: string;
17
+ timestamp: string;
18
+ };
19
+ export type FeedbackPayload = {
20
+ comment: string;
21
+ screenshot?: Screenshot;
22
+ metadata: Metadata;
23
+ console: ConsoleEntry[];
24
+ };
25
+ export type Position = 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
26
+ export type TextConfig = {
27
+ welcomeMessage: {
28
+ text: string;
29
+ closeAriaLabel: string;
30
+ };
31
+ feedbackForm: {
32
+ title: string;
33
+ placeholder: string;
34
+ screenshotAlt: string;
35
+ submitButton: string;
36
+ minimizeTitle: string;
37
+ expandTitle: string;
38
+ closeTitle: string;
39
+ showFormTitle: string;
40
+ };
41
+ notification: {
42
+ successTitle: string;
43
+ errorTitle: string;
44
+ errorMessage: string;
45
+ hideTitle: string;
46
+ };
47
+ drawingTooltip: {
48
+ text: string;
49
+ };
50
+ };
51
+ export type EchoConfig = {
52
+ onSubmit: (data: FeedbackPayload) => Promise<Response | void>;
53
+ position?: Position;
54
+ primaryColor?: `#${string}`;
55
+ textConfig?: Partial<TextConfig>;
56
+ };
57
+ export type FullEchoConfig = Required<EchoConfig> & {
58
+ textConfig: TextConfig;
59
+ };
60
+ export declare const POSITIONS: Record<Position, {
61
+ [key: string]: string;
62
+ }>;
63
+ export type Point = {
64
+ x: number;
65
+ y: number;
66
+ };
67
+ export type ShapeType = 'rectangle' | 'path';
68
+ export type DrawingTool = 'rectangle' | 'path';
69
+ export type Shape = {
70
+ id: string;
71
+ type: ShapeType;
72
+ color: string;
73
+ points: Point[];
74
+ };
75
+ export type IconProps = {
76
+ size?: number;
77
+ stroke?: string;
78
+ strokeWidth?: number;
79
+ class?: string;
80
+ style?: any;
81
+ fill?: string;
82
+ };
83
+ export type Notification = {
84
+ show: boolean;
85
+ type: 'success' | 'error' | null;
86
+ message: string | null;
87
+ };
@@ -0,0 +1,2 @@
1
+ export declare const calculateLuminance: (hexColor: string) => number;
2
+ export declare const getContrastColor: (hexColor: string) => string;
@@ -0,0 +1 @@
1
+ export declare const deepMerge: (target: any, source: any) => any;
@@ -0,0 +1,4 @@
1
+ import type { ConsoleEntry } from '~/types';
2
+ export declare const setupConsole: () => void;
3
+ export declare const cleanupConsole: () => void;
4
+ export declare const getConsoleBuffer: () => ConsoleEntry[];
@@ -0,0 +1 @@
1
+ export declare const debounce: <T extends (...args: any[]) => void>(func: T, wait: number) => (...args: Parameters<T>) => void;
@@ -0,0 +1 @@
1
+ export declare const isMobileDevice: () => boolean;
@@ -0,0 +1,5 @@
1
+ import type { Point } from '~/types';
2
+ export declare const getPointFromEvent: (e: MouseEvent | TouchEvent, { useClientCoords }?: {
3
+ useClientCoords?: boolean;
4
+ }) => Point;
5
+ export declare const getDistance: (p1: Point, p2: Point) => number;
@@ -0,0 +1 @@
1
+ export declare const formatPath: (path: string) => string;
@@ -0,0 +1,8 @@
1
+ import type { Point } from '~/types';
2
+ export declare const getRectFromPoints: (points: Point[]) => {
3
+ x: number;
4
+ y: number;
5
+ width: number;
6
+ height: number;
7
+ } | null;
8
+ export declare const getPathFromPoints: (points: Point[]) => string | null;
@@ -0,0 +1,13 @@
1
+ export * from './color';
2
+ export * from './common';
3
+ export * from './console';
4
+ export * from './debounce';
5
+ export * from './device';
6
+ export * from './events';
7
+ export * from './format';
8
+ export * from './geometry';
9
+ export * from './listeners';
10
+ export * from './screenshot';
11
+ export * from './storage';
12
+ export * from './svg';
13
+ export * from './validators';
@@ -0,0 +1,22 @@
1
+ export declare const registerKeyListener: (key: string, callback: (e: KeyboardEvent) => void) => void;
2
+ export declare const registerWindowEventListener: {
3
+ <K extends keyof WindowEventMap>(props: {
4
+ event: K;
5
+ callback: (e: WindowEventMap[K]) => void;
6
+ onMount?: () => void;
7
+ onCleanup?: () => void;
8
+ }): void;
9
+ (props: {
10
+ event: string;
11
+ callback: (e: Event) => void;
12
+ onMount?: () => void;
13
+ onCleanup?: () => void;
14
+ }): void;
15
+ };
16
+ export declare const registerMutationObserver: (props: {
17
+ target: Node;
18
+ options?: MutationObserverInit;
19
+ callback: (mutations: MutationRecord[]) => void;
20
+ onMount?: () => void;
21
+ onCleanup?: () => void;
22
+ }) => void;
@@ -0,0 +1,2 @@
1
+ import type { Screenshot } from '~/types';
2
+ export declare const captureScreenshot: () => Promise<Screenshot | undefined>;
@@ -0,0 +1,28 @@
1
+ import { DrawingState, FeedbackState } from '~/stores';
2
+ import type { Shape } from '~/types';
3
+ type StoredPageState = {
4
+ feedback: {
5
+ comment: string;
6
+ };
7
+ drawing: {
8
+ shapes: Shape[];
9
+ };
10
+ latestQuery?: string;
11
+ };
12
+ export declare const dispatchStorageChange: () => void;
13
+ export declare const getStorageKey: (key: string) => string;
14
+ export declare const getFromStorage: <T>(key: string, defaultValue: T) => T;
15
+ export declare const setToStorage: <T>(key: string, value: T) => void;
16
+ export declare const getPageKey: () => string;
17
+ export declare const savePageState: (pageKey: string, state: {
18
+ feedback: FeedbackState;
19
+ drawing: DrawingState;
20
+ }) => void;
21
+ export declare const loadPageState: (pageKey: string) => StoredPageState | null;
22
+ export declare const clearPageState: (pageKey: string) => void;
23
+ export declare const getStoredPagesCount: () => number;
24
+ export declare const getStoredPages: () => {
25
+ path: string;
26
+ state: StoredPageState;
27
+ }[];
28
+ export {};
@@ -0,0 +1,13 @@
1
+ export declare const generateCutoutPath: (dimensions: {
2
+ width: number;
3
+ height: number;
4
+ }, currentPoints: {
5
+ x: number;
6
+ y: number;
7
+ }[], shapes: {
8
+ type: string;
9
+ points: {
10
+ x: number;
11
+ y: number;
12
+ }[];
13
+ }[]) => string;
@@ -0,0 +1,2 @@
1
+ import type { EchoConfig } from '~/types';
2
+ export declare const validateOptions: (options: EchoConfig) => void;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@contember/echo",
3
3
  "license": "Apache-2.0",
4
- "version": "0.0.27",
4
+ "version": "0.0.28",
5
5
  "type": "module",
6
6
  "author": "neumie@neumie.dev",
7
7
  "keywords": [