New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Expose $entry
variable to Markdoc
#6588
Conversation
🦋 Changeset detectedLatest commit: 1071319 The changes in this PR will be included in the next version bump. Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! For a second I thought it's a wordplay on Sentry 🙈
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good job @bholmesdev, docs LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I admit that I'm struggling to understand the function setContentEntryModuleCache
. It does a lot of stuff. Of course, I don't have much knowledge of the tool yet, so I lack a lot of contexts.
fileId: string; | ||
pluginContext: PluginContext; | ||
}): Promise<ContentEntryModule> { | ||
contentEntryModuleByIdCache.set(fileId, 'loading'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I admit that having a "loading" value inside a cache is not something you see often. Usually, you either have or do not have value. Would you mind explaining how this caching works?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, sorry for the unconventional implementation! Trying to track 3 possible states here:
- Module has not been cached yet (
undefined
) - Module is being resolved, but the async operation hasn't completed yet (
'loading'
) - Module has been resolved and cached (
ContentEntryModule
)
This gets around an annoying problem I hit in production builds, where Vite tries to load a content entry's rendered content before its frontmatter module has been resolved. By tracking which cached entries haven't resolved yet with 'loading'
, we can queue up a promise to "wait" for that frontmatter module to be resolved before rendering the post's content module. I tried implementing this with cached promises instead, but truthfully couldn't wrap my head around the complexity for a friday evening 😅
If this is too confusing, I'm happy to refactor. Let me know if there's an implementation I'm not seeing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for the thorough explanation! I understand now because we have unconventional implementation. Maybe it's worth documenting it with a comment, so other developers will know why we have this caching system.
I think the best approach is to return promises from the cache if we know that a value is always returned when the promise is fulfilled. Undoubtedly the implementation is trickier, but it allows us to use just two states, without the burden of maintaining three states.
Although, I understand if the implementation becomes trickier.
If I would suggest a solution, maybe wrapping the whole function into a new Promise
should be enough. Instead of return value
we do resolve(value)
This reverts commit 484ccb1.
Co-authored-by: Yan Thomas <61414485+Yan-Thomas@users.noreply.github.com>
c4aa553
to
023703a
Compare
fileId: string; | ||
pluginContext: PluginContext; | ||
}): Promise<ContentEntryModule> { | ||
contentEntryModuleByIdCache.set(fileId, 'loading'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for the thorough explanation! I understand now because we have unconventional implementation. Maybe it's worth documenting it with a comment, so other developers will know why we have this caching system.
I think the best approach is to return promises from the cache if we know that a value is always returned when the promise is fulfilled. Undoubtedly the implementation is trickier, but it allows us to use just two states, without the burden of maintaining three states.
Although, I understand if the implementation becomes trickier.
If I would suggest a solution, maybe wrapping the whole function into a new Promise
should be enough. Instead of return value
we do resolve(value)
@ematipico Alright, rewrote the cache implementation and added a thorough code comment. It's not quite the suggestion you made (missed that while I was working) but I think this puts us in a better spot. Opening for re-review if you want to take a look! We can refine from here in a follow-up PR as well. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The implementation is way better now! Thank you for taking the time for refactoring it!
Changes
id
,slug
, andcollection
name.getRenderModule()
helper on our internaladdContentEntryType
API. This exposes the parsedentry
to your Vite loader for use while generating the module (ex. to expose an$entry
variable to the Markdoc transformer). This also standardizes how the result of.render()
is generated. Before, integration authors would need to wire up a separate Vite plugin that resolves modules of your preferred extension and hope this meshes with Astro's content collection API (see diff here). By standardizing this, we can change how and when rendered modules are loaded in the future without breaking changes.getRenderModule()
.Testing
$entry
variableDocs
$entry