Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@data-eden/athena

Package Overview
Dependencies
Maintainers
4
Versions
41
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@data-eden/athena - npm Package Compare versions

Comparing version 0.13.2 to 0.14.0

244

__tests__/client.test.ts

@@ -1,7 +0,44 @@

import { describe, test, expect, beforeEach } from 'vitest';
import { AthenaClient } from '../src/client.js';
import {
describe,
test,
expect,
beforeEach,
beforeAll,
afterAll,
afterEach,
} from 'vitest';
import http from 'http';
import { readFileSync } from 'fs';
import { resolve } from 'path';
import { createServer } from '@data-eden/shared-test-utilities';
import { createSignal } from '@signalis/core';
import { gql } from '@data-eden/codegen/gql';
import { Mocker } from '@data-eden/mocker';
import { type PeopleQuery } from './__generated/client.test.graphql';
import { AthenaClient } from '../src/client.js';
import type { ReactiveSignal } from '../src/types.js';
const schema = readFileSync(
resolve(
__dirname,
'..',
'..',
'..',
'internal-packages/react-graphql-test-app/src/graphql/schema.graphql'
),
'utf8'
);
const peopleQuery = gql<PeopleQuery>`
query people {
people {
id
name
}
}
`;
function adapter<T>(v: T): ReactiveSignal<T> {

@@ -16,30 +53,22 @@ return createSignal(v, false);

function hashCode(str: string) {
let hash = 0;
for (let i = 0, len = str.length; i < len; i++) {
let chr = str.charCodeAt(i);
// eslint-disable-next-line no-bitwise
hash = (hash << 5) - hash + chr;
// eslint-disable-next-line no-bitwise
hash |= 0; // Convert to 32bit integer
}
return hash.toString();
}
const mocker = new Mocker({
schema,
});
describe('client', () => {
let client: AthenaClient;
describe('processEntities', () => {
let client: AthenaClient;
beforeEach((test) => {
client = new AthenaClient({
url: '/example',
adapter: adapter,
getCacheKey: (v: Entity, parent: Entity) => {
return `${v.__typename}:${(
v?.id ?? hashCode(JSON.stringify({ ...v, parent: parent?.id }))
).replace(/:/g, '&')}`;
},
beforeEach((test) => {
client = new AthenaClient({
url: '/example',
adapter: adapter,
getCacheKey: (v: Entity, parent: Entity) => {
if (v.id) {
return `${v.__typename}:${v?.id}`;
}
},
});
});
});
describe('processEntities', () => {
test('parses a single entity', async () => {

@@ -322,3 +351,168 @@ const document = {

});
test('should be able to handle entities with no cacheable nested values', async () => {
const document = {
paginatedCommentsPage: {
threadUrn: 'urn:li:activity:7070125034782027776',
id: 'urn:li:activity:7070125034782027776',
comments: [
{
socialMetadata: {
reactionSummaries: [
{
count: 1,
type: 'APPRECIATION',
__typename: 'ReactionSummary',
},
],
id: 'urn:li:comment:(activity:7070125034782027776,7071631601935249410)',
viewerReaction: {
type: 'APPRECIATION',
},
commentSummary: {
count: 0,
},
__typename: 'SocialMetadata',
},
createdAt: 1686008358464,
id: 'urn:li:comment:(urn:li:activity:7070125034782027776,7071631601935249410)',
author: {
firstName: 'Bob',
lastName: 'Bobberson',
profilePicture: {
url: 'https://media.licdn.com/dms/image/C5603AQGjVp-oZT1bnw/profile-displayphoto-shrink_400_400/0/1561741260600?e=1692835200&v=beta&t=kUlBHG3Fe5z4ao2vgCyP8DVR6nERCy4fTXxAnCxo9F8',
},
id: 'urn:li:member:655184127',
profileCanonicalUrl: {
url: 'https://www.linkedin.com/in/bob-bobberson',
},
__typename: 'Profile',
memberUrn: 'urn:li:member:655184127',
networkDistance: {
distance: 'SELF',
},
headline: 'Code Janitor at LinkedIn',
},
__typename: 'Comment',
media: [],
message: [
{
__typename: 'AttributedTextSegment',
text: "hello again'",
},
],
},
],
__typename: 'PaginatedCommentsPage',
},
};
const result = await client.processEntities(document);
expect(
result.paginatedCommentsPage.comments[0].socialMetadata
.reactionSummaries[0].type
).toEqual('APPRECIATION');
expect(
result.paginatedCommentsPage.comments[0].socialMetadata
.reactionSummaries[0].count
).toEqual(1);
expect(
result.paginatedCommentsPage.comments[0].socialMetadata.viewerReaction
.type
).toEqual('APPRECIATION');
await client.processEntities({
toggleSocialReaction: {
socialMetadata: {
reactionSummaries: [
{
count: 1,
type: 'INTEREST',
__typename: 'ReactionSummary',
},
],
id: 'urn:li:comment:(activity:7070125034782027776,7071631601935249410)',
viewerReaction: {
type: 'INTEREST',
__typename: 'Reaction',
},
commentSummary: {
count: 0,
__typename: 'CommentSummary',
},
__typename: 'SocialMetadata',
},
__typename: 'ToggleSocialReactionResult',
responseCode: 'OK_200',
},
});
expect(
result.paginatedCommentsPage.comments[0].socialMetadata
.reactionSummaries[0].type
).toEqual('INTEREST');
expect(
result.paginatedCommentsPage.comments[0].socialMetadata.viewerReaction
.type
).toEqual('INTEREST');
});
});
describe('query', async () => {
const server = await createServer();
beforeAll(async () => await server.listen());
afterEach(() => server.reset());
afterAll(() => server.close());
test('should be able to query a basic endpoint', async () => {
const client = new AthenaClient({
url: server.buildUrl('/graphql'),
adapter: adapter,
getCacheKey: (v: Entity, parent: Entity) => {
if (v.id) {
return `${v.__typename}:${v?.id}`;
}
},
});
server.post(
'/graphql',
async (
request: http.IncomingMessage,
response: http.ServerResponse
) => {
response.writeHead(200, { 'Content-Type': 'application/json' });
response.end(
JSON.stringify({
data: await mocker.mock(peopleQuery, {
people: [
{
id: 12,
name: 'Bob',
},
],
}),
})
);
}
);
const { data, error } = await client.query(peopleQuery, {});
expect(error).toBeUndefined();
expect(data).toMatchInlineSnapshot(`
{
"people": [
{
"__typename": "Person",
"id": 12,
"name": "Bob",
},
],
}
`);
});
});
});

2

dist/signal-cache.d.ts

@@ -21,3 +21,3 @@ import type { CacheKey, PropertyPath } from './client.js';

links: Map<string, Link>;
records: Map<string, Record<string, Scalar>>;
records: Map<string, Record<string, Scalar> | WithSignal<Entity>>;
signals: Map<string, WeakRef<WithSignal<Entity>>>;

@@ -24,0 +24,0 @@ private registry;

@@ -50,3 +50,3 @@ import type { buildCache } from '@data-eden/cache';

}
export type IdFetcher<T = any> = (v: T, parent: T) => string;
export type IdFetcher<T = any> = (v: T, parent: T) => string | undefined;
//# sourceMappingURL=types.d.ts.map
{
"name": "@data-eden/athena",
"version": "0.13.2",
"version": "0.14.0",
"repository": {

@@ -27,3 +27,3 @@ "type": "git",

"dependencies": {
"@data-eden/cache": "^0.13.2",
"@data-eden/cache": "^0.14.0",
"date-fns": "^2.30.0",

@@ -33,2 +33,5 @@ "lodash-es": "^4.17.21"

"devDependencies": {
"@data-eden/codegen": "0.14.0",
"@data-eden/mocker": "0.14.0",
"@data-eden/shared-test-utilities": "0.14.0",
"@graphql-typed-document-node/core": "^3.2.0",

@@ -35,0 +38,0 @@ "@signalis/core": "^0.1.0",

@@ -202,2 +202,7 @@ import type { Cache } from '@data-eden/cache';

if (!key) {
// if we don't have a key it is not cacheable and must be cached based on the parent
continue;
}
// replace the entity object with the key we're using to store it in the cache so that we can

@@ -204,0 +209,0 @@ // later replace the key with the reactive entity

@@ -53,3 +53,3 @@ import { addMilliseconds, getTime } from 'date-fns';

links = new Map<string, Link>();
records = new Map<string, Record<string, Scalar>>();
records = new Map<string, Record<string, Scalar> | WithSignal<Entity>>();
signals = new Map<string, WeakRef<WithSignal<Entity>>>();

@@ -145,7 +145,19 @@ private registry: FinalizationRegistry<string>;

const arrayLink: Array<string> = [];
const recordArray: any[] = [];
value.forEach((link) => {
if (isLinkNode(link)) {
arrayLink.push(link.__link);
} else {
// we don't have a link and we need to attach this to the value itself as the reactivity is owned by the parent
recordArray.push(link);
}
});
// We only want to update the array value on the entity if the record has an array value or if the record has a length
// This is to ensure we update the record with an empty array if had an original value
if (
recordArray.length > 0 ||
(record[entityKey] && Array.isArray(record[entityKey]))
) {
record[entityKey] = recordArray;
}
links[entityKey] = arrayLink;

@@ -236,3 +248,7 @@ } else if (isLinkNode(value)) {

const toRemove = parentArray.filter((v) => {
return !value.includes(this.getCacheKey(v, parent));
const key = this.getCacheKey(v, parent);
// if there is no key we can't consistency manage it.
// it will get overriden when new values are returned on the parent object
return key && !value.includes(key);
});

@@ -299,2 +315,6 @@

// in order to get consistency updates on non managed field updates we set the signal if we have it
// so we can update it in storeEntity
this.records.set(entityKey, root);
return root;

@@ -301,0 +321,0 @@ }

@@ -69,2 +69,2 @@ import type { buildCache } from '@data-eden/cache';

export type IdFetcher<T = any> = (v: T, parent: T) => string;
export type IdFetcher<T = any> = (v: T, parent: T) => string | undefined;
import { defineConfig } from 'vitest/config';
import { resolve } from 'node:path';
import { rollupPlugin } from '@data-eden/codegen';
export default defineConfig({
plugins: [
rollupPlugin({
baseDir: resolve(__dirname, '__tests__'),
schemaPath: resolve(
__dirname,
'..',
'..',
'internal-packages',
'react-graphql-test-app',
'src',
'graphql',
'schema.graphql'
),
documents: ['**/*.test.ts'],
extension: '.graphql.ts',
disableSchemaTypesGeneration: false,
production: false,
}),
],
test: {
testTimeout: 10_000,
include: ['__tests__/**/*.test.ts'],
},

@@ -11,4 +32,5 @@ resolve: {

'@data-eden/athena': resolve(__dirname, './src'),
'@data-eden/mocker': resolve(__dirname, '../mocker/src'),
},
},
});

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc