@ossy/resources 3.11.1 → 3.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +5 -5
- package/src/en.translations.json +0 -4
- package/src/index.js +0 -2
- package/src/resource-stream.js +5 -7
- package/src/sv.translations.json +0 -4
- package/src/create-page-view.action.js +0 -1
- package/src/create-page-view.task.js +0 -39
- package/src/get-page-view-stats.action.js +0 -1
- package/src/get-page-view-stats.task.js +0 -63
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ossy/resources",
|
|
3
3
|
"description": "Resource domain — aggregate and events for the Ossy resource model",
|
|
4
|
-
"version": "3.
|
|
4
|
+
"version": "3.12.0",
|
|
5
5
|
"private": false,
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "./src/index.js",
|
|
@@ -23,9 +23,9 @@
|
|
|
23
23
|
"src": "./src"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@ossy/event-store": "^3.
|
|
27
|
-
"@ossy/fold": "^3.
|
|
28
|
-
"@ossy/platform": "^3.
|
|
26
|
+
"@ossy/event-store": "^3.12.0",
|
|
27
|
+
"@ossy/fold": "^3.12.0",
|
|
28
|
+
"@ossy/platform": "^3.12.0",
|
|
29
29
|
"@ossy/schema": "^3.8.0"
|
|
30
30
|
},
|
|
31
31
|
"peerDependencies": {
|
|
@@ -49,5 +49,5 @@
|
|
|
49
49
|
"/src",
|
|
50
50
|
"README.md"
|
|
51
51
|
],
|
|
52
|
-
"gitHead": "
|
|
52
|
+
"gitHead": "c2650803219ad1831559b512848358d9550ffad2"
|
|
53
53
|
}
|
package/src/en.translations.json
CHANGED
|
@@ -29,10 +29,6 @@
|
|
|
29
29
|
"@ossy/resources/actions/update-access.description": "Change access settings for a resource",
|
|
30
30
|
"@ossy/resources/actions/upload-named-version.label": "Upload named version",
|
|
31
31
|
"@ossy/resources/actions/upload-named-version.description": "Upload a named version of a resource file",
|
|
32
|
-
"@ossy/resources/actions/create-page-view.label": "Create page view",
|
|
33
|
-
"@ossy/resources/actions/create-page-view.description": "Record a page view analytics event",
|
|
34
|
-
"@ossy/resources/actions/get-page-view-stats.label": "Get page view stats",
|
|
35
|
-
"@ossy/resources/actions/get-page-view-stats.description": "Fetch aggregated page view statistics",
|
|
36
32
|
"resources/create/generic.documentTitle": "Create resource",
|
|
37
33
|
"create-directory.documentTitle": "Create directory",
|
|
38
34
|
"create-document.documentTitle": "Create document",
|
package/src/index.js
CHANGED
|
@@ -39,8 +39,6 @@ export { metadata as OpenView } from './open-view.action.js'
|
|
|
39
39
|
export { metadata as ViewList } from './view-list.action.js'
|
|
40
40
|
export { metadata as ViewGrid } from './view-grid.action.js'
|
|
41
41
|
export { metadata as DoneSelecting } from './done-selecting.action.js'
|
|
42
|
-
export { metadata as CreatePageView } from './create-page-view.action.js'
|
|
43
|
-
export { metadata as GetPageViewStats } from './get-page-view-stats.action.js'
|
|
44
42
|
export * from './AudioResource.jsx'
|
|
45
43
|
export * from './CreateDirectory.jsx'
|
|
46
44
|
export * from './CreateDocument.jsx'
|
package/src/resource-stream.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { nanoid } from 'nanoid'
|
|
2
|
-
import { EventStore, Mongo, withMongoReconnect } from '@ossy/event-store'
|
|
2
|
+
import { EventStore, Mongo, stampAppendedEvent, withMongoReconnect } from '@ossy/event-store'
|
|
3
3
|
import { createDefaultReducer } from '@ossy/fold'
|
|
4
4
|
import { createLogger } from '@ossy/observability'
|
|
5
5
|
|
|
@@ -42,14 +42,12 @@ export class ResourceStream {
|
|
|
42
42
|
static Add (event) {
|
|
43
43
|
return stream => {
|
|
44
44
|
const version = stream.version + 1
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
type: event.type ?? stream.events[0]?.type ?? stream.state?.type,
|
|
48
|
-
id: nanoid(),
|
|
49
|
-
created: Date.now(),
|
|
45
|
+
const type = event.type ?? stream.events[0]?.type ?? stream.state?.type
|
|
46
|
+
const saved = stampAppendedEvent(event, {
|
|
50
47
|
resourceId: stream.id,
|
|
51
48
|
version,
|
|
52
|
-
|
|
49
|
+
type,
|
|
50
|
+
})
|
|
53
51
|
return EventStore.AppendResourceEvent(saved)
|
|
54
52
|
.then(() => {
|
|
55
53
|
stream.version = version
|
package/src/sv.translations.json
CHANGED
|
@@ -29,10 +29,6 @@
|
|
|
29
29
|
"@ossy/resources/actions/update-access.description": "Ändra åtkomstinställningar för en resurs",
|
|
30
30
|
"@ossy/resources/actions/upload-named-version.label": "Ladda upp namngiven version",
|
|
31
31
|
"@ossy/resources/actions/upload-named-version.description": "Ladda upp en namngiven version av en resursfil",
|
|
32
|
-
"@ossy/resources/actions/create-page-view.label": "Skapa sidvisning",
|
|
33
|
-
"@ossy/resources/actions/create-page-view.description": "Registrera en sidvisningshändelse för analys",
|
|
34
|
-
"@ossy/resources/actions/get-page-view-stats.label": "Hämta sidvisningsstatistik",
|
|
35
|
-
"@ossy/resources/actions/get-page-view-stats.description": "Hämta aggregerad statistik för sidvisningar",
|
|
36
32
|
"resources/create/generic.documentTitle": "Skapa resurs",
|
|
37
33
|
"create-directory.documentTitle": "Skapa mapp",
|
|
38
34
|
"create-document.documentTitle": "Skapa dokument",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export const metadata = { id: '@ossy/resources/actions/create-page-view', access: 'workspace' }
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import { nanoid } from 'nanoid'
|
|
2
|
-
import { Aggregate } from '@ossy/event-store'
|
|
3
|
-
import { Workspace } from '@ossy/workspaces/server'
|
|
4
|
-
import { ResourcesEvents } from './resources.events.js'
|
|
5
|
-
import { commitResource } from './resource-stream.helpers.js'
|
|
6
|
-
|
|
7
|
-
export const metadata = { id: '@ossy/resources/tasks/create-page-view' }
|
|
8
|
-
|
|
9
|
-
const PAGE_VIEW_SCHEMA_ID = '@ossy/web/schema/page-view'
|
|
10
|
-
const PAGE_VIEW_LOCATION = '/@ossy/analytics/page-views/'
|
|
11
|
-
|
|
12
|
-
export async function run ({ payload, req }) {
|
|
13
|
-
const workspaceId = payload?.workspaceId ?? req?.workspaceId
|
|
14
|
-
if (!workspaceId) throw Object.assign(new Error('workspaceId is required'), { status: 400 })
|
|
15
|
-
|
|
16
|
-
const workspace = await Aggregate.Of(Workspace, workspaceId).then(Aggregate.View())
|
|
17
|
-
|
|
18
|
-
const contentInput = {
|
|
19
|
-
...(payload ?? {}),
|
|
20
|
-
userAgent: payload?.userAgent ?? req?.headers?.['user-agent'],
|
|
21
|
-
eventAt: payload?.eventAt ?? Date.now(),
|
|
22
|
-
path: payload?.path ?? '/',
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
const resourceId = nanoid()
|
|
26
|
-
const event = ResourcesEvents.Created({
|
|
27
|
-
resourceId,
|
|
28
|
-
schemaId: PAGE_VIEW_SCHEMA_ID,
|
|
29
|
-
createdBy: payload?.userId ?? req?.userId ?? 'public',
|
|
30
|
-
belongsTo: workspace.id,
|
|
31
|
-
location: PAGE_VIEW_LOCATION,
|
|
32
|
-
name: `${Date.now()}`,
|
|
33
|
-
content: contentInput,
|
|
34
|
-
access: 'restricted',
|
|
35
|
-
})
|
|
36
|
-
|
|
37
|
-
const resource = await commitResource(event)
|
|
38
|
-
return { id: resource.id }
|
|
39
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export const metadata = { id: '@ossy/resources/actions/get-page-view-stats', access: 'workspace' }
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import { Aggregate } from '@ossy/event-store'
|
|
2
|
-
import { Workspace } from '@ossy/workspaces/server'
|
|
3
|
-
|
|
4
|
-
export const metadata = { id: '@ossy/resources/tasks/get-page-view-stats' }
|
|
5
|
-
|
|
6
|
-
const PAGE_VIEW_SCHEMA_ID = '@ossy/web/schema/page-view'
|
|
7
|
-
const PAGE_VIEW_LOCATION = '/@ossy/analytics/page-views/'
|
|
8
|
-
|
|
9
|
-
function parseMillis(input, fallback) {
|
|
10
|
-
if (input === undefined || input === null || input === '') return fallback
|
|
11
|
-
const n = Number(input)
|
|
12
|
-
if (!Number.isFinite(n) || n <= 0) return fallback
|
|
13
|
-
return n
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export async function run({ payload, req }) {
|
|
17
|
-
const workspaceId = payload?.workspaceId ?? req?.workspaceId
|
|
18
|
-
if (!workspaceId) throw Object.assign(new Error('workspaceId is required'), { status: 400 })
|
|
19
|
-
|
|
20
|
-
const workspace = await Aggregate.Of(Workspace, workspaceId).then(Aggregate.View())
|
|
21
|
-
|
|
22
|
-
const now = Date.now()
|
|
23
|
-
const defaultFrom = now - (30 * 24 * 60 * 60 * 1000)
|
|
24
|
-
const from = parseMillis(payload?.from ?? req?.query?.from, defaultFrom)
|
|
25
|
-
const to = parseMillis(payload?.to ?? req?.query?.to, now)
|
|
26
|
-
const topLimit = Math.min(Math.max(Number(payload?.limit ?? req?.query?.limit ?? 10), 1), 50)
|
|
27
|
-
|
|
28
|
-
const baseMatch = {
|
|
29
|
-
type: PAGE_VIEW_SCHEMA_ID,
|
|
30
|
-
'state.status': { $ne: 'removed' },
|
|
31
|
-
'state.belongsTo': workspace.id,
|
|
32
|
-
'state.location': PAGE_VIEW_LOCATION,
|
|
33
|
-
'state.content.eventAt': { $gte: from, $lte: to },
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
const [dailyViews, topPaths, totals] = await Promise.all([
|
|
37
|
-
Aggregate.Collection.aggregate([
|
|
38
|
-
{ $match: baseMatch },
|
|
39
|
-
{ $project: { date: { $dateToString: { format: '%Y-%m-%d', date: { $toDate: '$state.content.eventAt' } } } } },
|
|
40
|
-
{ $group: { _id: '$date', views: { $sum: 1 } } },
|
|
41
|
-
{ $sort: { _id: 1 } },
|
|
42
|
-
]).toArray(),
|
|
43
|
-
Aggregate.Collection.aggregate([
|
|
44
|
-
{ $match: baseMatch },
|
|
45
|
-
{ $group: { _id: '$state.content.path', views: { $sum: 1 } } },
|
|
46
|
-
{ $sort: { views: -1 } },
|
|
47
|
-
{ $limit: topLimit },
|
|
48
|
-
{ $project: { _id: 0, path: '$_id', views: 1 } },
|
|
49
|
-
]).toArray(),
|
|
50
|
-
Aggregate.Collection.aggregate([
|
|
51
|
-
{ $match: baseMatch },
|
|
52
|
-
{ $count: 'views' },
|
|
53
|
-
]).toArray(),
|
|
54
|
-
])
|
|
55
|
-
|
|
56
|
-
return {
|
|
57
|
-
from,
|
|
58
|
-
to,
|
|
59
|
-
totalViews: totals?.[0]?.views || 0,
|
|
60
|
-
dailyViews: dailyViews.map(x => ({ date: x._id, views: x.views })),
|
|
61
|
-
topPaths,
|
|
62
|
-
}
|
|
63
|
-
}
|