Page Menu
Home
Sealhub
Search
Configure Global Search
Log In
Files
F8928878
cached-value.js
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
4 KB
Referenced Files
None
Subscribers
None
cached-value.js
View Options
"use strict"
;
const
{
getDateTime
}
=
require
(
"../../../utils/get-datetime.js"
);
module
.
exports
=
app
=>
({
name
:
"cached-value"
,
get_description
:
function
()
{
return
"Caches custom values. Takes care of cache invalidation."
;
},
get_default_value
:
async
()
=>
null
,
value_path_after_field_name
:
".value"
,
is_proper_value
:
function
(
context
,
params
,
new_value
)
{
if
(
!
context
.
is_super
)
{
return
Promise
.
reject
(
"This is a read-only field"
);
}
return
this
.
_call_base_method
(
"is_proper_value"
,
context
,
params
,
new_value
);
},
filter_to_query
:
async
function
(
context
,
params
,
field_filter
)
{
return
this
.
_call_base_method
(
"filter_to_query"
,
context
,
params
,
field_filter
);
},
init
:
function
(
collection
,
field_name
,
params
)
{
const
{
refresh_on
,
get_value
,
base_field_type
}
=
params
;
this
.
_check_for_possible_recursive_edits
(
app
,
refresh_on
,
collection
.
name
,
field_name
);
const
create_action
=
refresh_on
.
find
(({
event_matcher
})
=>
event_matcher
.
containsAction
(
"create"
)
);
if
(
create_action
)
{
app
.
addHook
(
{
when
:
"after"
,
action
:
"start"
},
async
()
=>
await
this
.
_refresh_outdated_cache_values
(
create_action
,
collection
,
field_name
,
params
)
);
}
for
(
let
{
event_matcher
,
resource_id_getter
}
of
refresh_on
)
{
app
.
addHook
(
event_matcher
,
async
(
emitted_event
,
resource
)
=>
{
const
cache_resource_id
=
await
resource_id_getter
(
emitted_event
,
resource
);
await
app
.
run_action
(
new
app
.
Sealious
.
SuperContext
(
emitted_event
.
metadata
.
context
),
[
"collections"
,
collection
.
name
,
cache_resource_id
],
"edit"
,
{
[
field_name
]
:
await
get_value
(
emitted_event
.
metadata
.
context
,
cache_resource_id
),
}
);
});
}
},
_check_for_possible_recursive_edits
:
function
(
app
,
refresh_on
,
collection_name
,
field_name
)
{
const
{
Collection
,
Resource
}
=
app
.
Sealious
.
EventMatchers
;
const
doesAnyMatches
=
refresh_on
.
some
(({
event_matcher
})
=>
{
if
(
event_matcher
instanceof
Collection
||
event_matcher
instanceof
Resource
)
{
return
event_matcher
.
collection_name
===
collection_name
;
}
event_matcher
.
subject_path
.
test
(
`collections.
${
collection_name
}
`
);
});
if
(
doesAnyMatches
)
{
throw
new
Error
(
`In the
${
collection_name
}
collection definition you've tried to create the
${
field_name
}
cached-value field that refers to the collection itself. Consider using 'derived-value' field type to avoid problems with endless recurrence.`
);
}
},
_refresh_outdated_cache_values
:
async
function
(
create_action
,
collection
,
field_name
,
params
)
{
const
referenced_collection_name
=
create_action
.
event_matcher
.
collection_name
;
const
last_modified_resource
=
(
await
app
.
run_action
(
new
app
.
Sealious
.
SuperContext
(),
[
"collections"
,
referenced_collection_name
],
"show"
,
{
sort
:
{
"last_modified_context.timestamp"
:
"desc"
},
pagination
:
{
items
:
1
},
}
))[
0
];
if
(
!
last_modified_resource
)
{
return
;
}
const
last_modified_timestamp
=
last_modified_resource
.
last_modified_context
.
timestamp
;
const
outdated_resources
=
await
app
.
Datastore
.
aggregate
(
collection
.
name
,
[
{
$match
:
{
$or
:
[
{
[
`body.
${
field_name
}
.timestamp`
]
:
{
$lt
:
last_modified_timestamp
,
},
},
{
[
`body.
${
field_name
}
`
]
:
{
$exists
:
false
}
},
],
},
},
]
);
if
(
!
outdated_resources
)
{
return
;
}
const
context
=
new
app
.
Sealious
.
SuperContext
();
for
(
let
resource
of
outdated_resources
)
{
const
cache_value
=
await
this
.
encode
(
context
,
params
,
await
params
.
get_value
(
context
,
resource
.
sealious_id
)
);
await
app
.
Datastore
.
update
(
collection
.
name
,
{
sealious_id
:
resource
.
sealious_id
},
{
$set
:
{
[
`body.
${
field_name
}
`
]
:
cache_value
}
}
);
}
},
encode
:
async
function
(
context
,
params
,
value
)
{
return
{
timestamp
:
context
.
timestamp
,
value
:
await
this
.
_call_base_method
(
"encode"
,
context
,
params
,
value
),
};
},
decode
:
function
(
context
,
params
,
value_in_db
)
{
return
this
.
_call_base_method
(
"decode"
,
context
,
params
,
value_in_db
?
value_in_db
.
value
:
null
);
},
format
:
function
(
context
,
params
,
decoded_value
,
format
)
{
const
base_field_type
=
app
.
FieldType
(
params
.
base_field_type
.
name
);
return
base_field_type
.
format
(
context
,
params
.
base_field_type
.
params
||
{},
decoded_value
,
format
);
},
_call_base_method
(
method
,
context
,
params
,
arg
)
{
const
base_field_type
=
app
.
FieldType
(
params
.
base_field_type
.
name
);
return
base_field_type
[
method
](
context
,
params
.
base_field_type
.
params
||
{},
arg
);
},
});
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Sep 20, 20:57 (9 m, 58 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
949691
Default Alt Text
cached-value.js (4 KB)
Attached To
Mode
rS Sealious
Attached
Detach File
Event Timeline
Log In to Comment