Skip to content

Commit 57577f4

Browse files
committed
fixed KV
Signed-off-by: Sahil-simform <[email protected]>
1 parent ea021d5 commit 57577f4

File tree

661 files changed

+27722
-202
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

661 files changed

+27722
-202
lines changed
Lines changed: 60 additions & 201 deletions
Original file line numberDiff line numberDiff line change
@@ -1,219 +1,78 @@
1-
// filepath: /Users/sahil.t/StudioProjects/dynamic_chat_web/netlify/edge-functions/get-package-data.js
2-
// MANUAL TOGGLE: Set to true for production mode, false for local development mode
3-
const FORCE_PRODUCTION_MODE = true;
1+
// filepath: netlify/edge-functions/get-package-data.js
2+
import { getStore } from '@netlify/blobs';
43

5-
// The namespace used by the scheduled function
64
const NAMESPACE = 'package-scores';
75

8-
// Simple in-memory cache for local development
9-
const localCache = {
10-
data: {
11-
'package-data': JSON.stringify({
12-
'flutter': {
13-
grantedPoints: 150,
14-
maxPoints: 160,
15-
likeCount: 2817,
16-
downloadCount30Days: 156194,
17-
tags: [
18-
'publisher:simform.com',
19-
'sdk:flutter',
20-
'platform:android',
21-
'platform:ios',
22-
'platform:windows',
23-
'platform:linux',
24-
'platform:macos',
25-
'platform:web',
26-
'is:null-safe',
27-
'is:wasm-ready',
28-
'is:dart3-compatible',
29-
'license:mit',
30-
'license:fsf-libre',
31-
'license:osi-approved'
32-
],
33-
lastUpdated: '2025-04-24T20:09:55.534241'
34-
}
35-
}),
36-
'last-updated': JSON.stringify(new Date().toISOString())
37-
}
38-
};
6+
async function getPackageData(packageName) {
7+
const store = getStore({ name: NAMESPACE });
8+
const raw = await store.get(`package-${packageName}`);
9+
return raw ? JSON.parse(raw) : null;
10+
}
11+
12+
async function getAllPackageData() {
13+
const store = getStore({ name: NAMESPACE });
14+
const raw = await store.get('package-data');
15+
return raw ? JSON.parse(raw) : {};
16+
}
3917

40-
export default async (request, context) => {
18+
async function getLastUpdated() {
19+
const store = getStore({ name: NAMESPACE });
20+
const raw = await store.get('last-updated');
21+
return raw ? JSON.parse(raw) : null;
22+
}
23+
24+
export default async (request) => {
4125
try {
42-
// Parse the URL to get the package name
4326
const url = new URL(request.url);
4427
const packageName = url.searchParams.get('package');
45-
46-
// Log available context for debugging
47-
console.log(`Available context keys: ${Object.keys(context).join(', ')}`);
48-
if (context.env) {
49-
console.log(`Available env keys: ${Object.keys(context.env).join(', ')}`);
50-
}
51-
28+
5229
let data;
53-
let lastUpdated;
54-
let kvAccessMethod = 'none';
55-
56-
try {
57-
console.log('Attempting to access Netlify Edge KV Storage');
58-
59-
// Try several different ways to access KV storage based on the context
60-
let kv = null;
61-
62-
// Method 1: Try to get KV from context directly (binding in netlify.toml)
63-
if (context.KV) {
64-
console.log('Found KV in context.KV');
65-
kv = context.KV;
66-
}
67-
// Method 2: Try from context.env
68-
else if (context.env && context.env.KV) {
69-
console.log('Found KV in context.env.KV');
70-
kv = context.env.KV;
71-
}
72-
// Method 3: Try older netlify edge context pattern
73-
else if (context.site && context.site.kv) {
74-
console.log('Found KV in context.site.kv');
75-
kv = context.site.kv;
76-
}
77-
// Method 4: Try via global Netlify object
78-
else if (typeof Netlify !== 'undefined' && Netlify.env && Netlify.env.get) {
79-
console.log('Using global Netlify.env.get("KV")');
80-
kv = Netlify.env.get("KV");
81-
}
82-
83-
if (kv) {
84-
console.log('Successfully obtained KV namespace');
85-
86-
// Try with both namespaced and non-namespaced keys
87-
let keys = [];
88-
if (packageName) {
89-
keys = [
90-
`${NAMESPACE}:package-${packageName}`,
91-
`package-${packageName}`,
92-
`package-scores/package-${packageName}`
93-
];
94-
} else {
95-
keys = [
96-
`${NAMESPACE}:package-data`,
97-
`package-data`,
98-
`package-scores/package-data`
99-
];
100-
}
101-
102-
// Try each key until we find data
103-
for (const key of keys) {
104-
console.log(`Trying to access key: ${key}`);
105-
data = await kv.get(key);
106-
107-
if (data !== null && data !== undefined) {
108-
console.log(`Found data using key: ${key}`);
109-
kvAccessMethod = `kv-with-key-${key}`;
110-
break;
111-
}
112-
}
113-
114-
// Try each key for last updated
115-
if (data) {
116-
const updateKeys = [
117-
`${NAMESPACE}:last-updated`,
118-
`last-updated`,
119-
`package-scores/last-updated`
120-
];
121-
122-
for (const key of updateKeys) {
123-
lastUpdated = await kv.get(key);
124-
if (lastUpdated !== null && lastUpdated !== undefined) {
125-
break;
126-
}
30+
if (packageName) {
31+
data = await getPackageData(packageName);
32+
if (!data) {
33+
return new Response(
34+
JSON.stringify({
35+
error: 'Package not found',
36+
note: 'Data might not be populated yet by the scheduled function'
37+
}),
38+
{
39+
status: 404,
40+
headers: { 'Content-Type': 'application/json' }
12741
}
128-
}
129-
130-
if (!data) {
131-
throw new Error('No data found in KV store with any key pattern');
132-
}
133-
} else {
134-
throw new Error('KV namespace not available in Netlify environment');
42+
);
13543
}
136-
} catch (kvError) {
137-
console.error(`KV store access error: ${kvError.message}`);
138-
console.log('Falling back to in-memory cache due to KV access error');
139-
140-
// Access the in-memory cache
141-
if (packageName) {
142-
const allData = JSON.parse(localCache.data['package-data'] || '{}');
143-
data = allData[packageName] ? JSON.stringify(allData[packageName]) : null;
144-
} else {
145-
data = localCache.data['package-data'];
146-
}
147-
148-
lastUpdated = localCache.data['last-updated'];
149-
kvAccessMethod = 'localCacheFallback';
44+
} else {
45+
data = await getAllPackageData();
15046
}
151-
152-
// Handle case with no data found
153-
if (!data) {
154-
return new Response(JSON.stringify({
155-
error: packageName ? 'Package not found' : 'No data available',
156-
note: 'Data might not be populated yet by the scheduled function',
157-
accessMethod: kvAccessMethod
158-
}), {
159-
status: packageName ? 404 : 200,
47+
48+
const lastUpdated = await getLastUpdated();
49+
50+
return new Response(
51+
JSON.stringify({
52+
data,
53+
lastUpdated,
54+
environment: 'production',
55+
accessMethod: 'blob-storage'
56+
}),
57+
{
58+
status: 200,
16059
headers: {
16160
'Content-Type': 'application/json',
162-
'Cache-Control': 'no-cache'
61+
'Cache-Control': 'public, max-age=60'
16362
}
164-
});
165-
}
166-
167-
// Handle different KV response formats
168-
// Some KV implementations return { value: data }, others return data directly
169-
if (data && typeof data === 'object' && data.value !== undefined) {
170-
data = data.value;
171-
}
172-
if (lastUpdated && typeof lastUpdated === 'object' && lastUpdated.value !== undefined) {
173-
lastUpdated = lastUpdated.value;
174-
}
175-
176-
// Parse the data if needed
177-
if (typeof data === 'string') {
178-
try {
179-
data = JSON.parse(data);
180-
} catch (parseError) {
181-
console.log('Failed to parse data as JSON, returning as string');
182-
}
183-
}
184-
185-
// Parse lastUpdated if needed
186-
if (typeof lastUpdated === 'string') {
187-
try {
188-
lastUpdated = JSON.parse(lastUpdated);
189-
} catch (parseError) {
190-
console.log('Failed to parse lastUpdated as JSON, using as is');
19163
}
192-
}
193-
194-
return new Response(JSON.stringify({
195-
data,
196-
lastUpdated,
197-
environment: 'production',
198-
accessMethod: kvAccessMethod
199-
}), {
200-
status: 200,
201-
headers: {
202-
'Content-Type': 'application/json',
203-
'Cache-Control': 'public, max-age=60' // Cache for 1 minute
204-
}
205-
});
64+
);
20665
} catch (error) {
207-
console.error(`Error serving package data: ${error.message}`);
208-
return new Response(JSON.stringify({
209-
error: 'Failed to retrieve package data',
210-
message: error.message,
211-
stack: error.stack
212-
}), {
213-
status: 500,
214-
headers: {
215-
'Content-Type': 'application/json'
66+
console.error('Edge function error:', error);
67+
return new Response(
68+
JSON.stringify({
69+
error: 'Failed to retrieve package data',
70+
message: error.message
71+
}),
72+
{
73+
status: 500,
74+
headers: { 'Content-Type': 'application/json' }
21675
}
217-
});
76+
);
21877
}
219-
};
78+
};

netlify_functions/fetch-package-data.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ const { schedule } = require('@netlify/functions');
44
const { getPackageList, savePackageData } = require('./storage');
55

66
// This function runs every 1 minutes
7-
exports.handler = schedule('1 * * * *', async (event) => {
7+
exports.handler = schedule('*/1 * * * *', async (event) => {
88
try {
99
// Get list of packages we want to track
1010
const packages = await getPackageList();

node_modules/@netlify/functions/dist/chunk-6WDYR2HN.mjs renamed to node_modules/.deno/.deno.lock

File renamed without changes.

node_modules/.deno/.deno.lock.poll

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
4.53 KB
Binary file not shown.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

0 commit comments

Comments
 (0)